我做了一些 C++ 评估问题,偶然发现了这个棘手的程序。
#include <deque>
#include <iostream>
using namespace std;
template<typename T>
ostream & print(T &start, T &end)
{
for(; start != end; ++start)
{
cout<< *start<< " ";
}
return cout;
}
int main()
{
int tab[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
deque<int> d1(tab, tab+10);
deque<int> d2;
deque<int>::iterator it;
for(it = d1.begin(); it != d1.end(); ++it)
{
d2.push_back(d1[d1.end()-it-1]); //LINE I
}
print(d2.rbegin(), d2.rend()) << endl; //LINE II
return 0;
}
我选择了选项程序将成功运行并显示:1 2 3 4 5 6 7 8 9 10
我后来编译了程序来测试它,它没有编译错误信息:
$g++ -o main *.cpp main.cpp: In function ‘int main()’: main.cpp:25:17: error: cannot bind non-const lvalue reference of type ‘std::reverse_iterator<std::_Deque_iterator<int, int&, int*> >&’ to an rvalue of type ‘std::deque<int>::reverse_iterator {aka std::reverse_iterator<std::_Deque_iterator<int, int&, int*> >}’ print(d2.rbegin(), d2.rend()) << endl; //LINE II
~~~~~~~~~^~ main.cpp:6:32: note: initializing argument 1 of ‘std::ostream& print(T&, T&) [with T = std::reverse_iterator<std::_Deque_iterator<int, int&, int*> >; std::ostream = std::basic_ostream<char>]’ template<typename T> ostream & print(T &start, T &end)
^~~~~
这个错误信息实际上是选项之一,但我认为它不会编译。
我真的不明白这是什么问题。我想如果我改变print
函数的参数如下,那么它编译并成功运行:
template<typename T> ostream & print(T start, T end)
{
for(; start != end; ++start)
{
cout<< *start<< " ";
}
return cout;
}
这是为什么?如果print
函数的参数是引用,如何理解错误信息?
左值引用可以绑定到左值。如果print
通过左值引用获取其参数,则在从rbegin/rend
以下位置创建左值时,您的代码可以编译:
auto it1 = d2.rbegin();
auto it2 = d2.rend();
print(it1,it2); // pass Lvalues
当您调用 时print(d2.rbegin(),d2.rend())
,按值rbegin/rend
返回迭代器,因此这些迭代器是临时对象,并且由于将临时对象 (Rvalue) 绑定到 Lvalue 引用是非法的,因此您的代码无法编译。
迭代器是轻量级对象,您不需要通过引用传递它们,只需复制它们即可。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句