C 功能具有参考参数错误的迭代器错误.寻求解释
C++ function with reference parameters errors out for iterator. Seeking explanation
我做了一些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 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
函数的参数是引用?
lvalue参考可以绑定到lvalues。如果print
通过LVALUE参考进行参数,则当您从rbegin/rend
创建LVALUE时,您的代码可以编译:
auto it1 = d2.rbegin();
auto it2 = d2.rend();
print(it1,it2); // pass Lvalues
当您调用print(d2.rbegin(),d2.rend())
时,rbegin/rend
按值返回迭代器,因此这些迭代器是临时对象,并且由于将临时对象(rvalue)绑定到lvalue参考是非法的,因此您的代码不编译。
迭代器是轻量级的对象,您无需通过参考来传递它们,只需复制它们。
说明编译器错误
打印函数的参数是参考,但是const引用仍然是参考。如果我有一个按值返回(例如d2.begin()
)的表达式,则它只能绑定到const引用,因此您的打印函数使用const引用调用。
修复
因为print
带有迭代器,因此您应该按值通过它们。迭代器的复制是微不足道的(通常是编译器可以直接在CPU的寄存器中传递,因此甚至无需副本)。我们可以通过删除参考文献来重写print
:
template<typename T>
ostream & print(T start, T end)
{
for(; start != end; ++start)
{
cout<< *start<< " ";
}
return cout;
}
相关文章:
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- 初始化迭代器错误 C++ 在 GCC 编译器中
- 迭代器类的重载前缀增量运算符会引发分段错误
- 为什么我在使用 istream 迭代器时会出现 seg 错误?
- 在静态库中使用输出迭代器时出现链接器错误
- 在分配和发布递增循环迭代器时C++无限循环(gcc 错误?
- 比较迭代器会使程序崩溃,而不会在自定义气泡排序实现中出现错误
- C++结构编译器错误询问向量的迭代器
- 编译时二叉搜索树错误的反向迭代器表示"no matching function call for operator=()"
- 编译错误 std::vector<std::shared_ptr<T>>迭代器和擦除方法
- 赛松迭代器错误
- 向量迭代器不兼容的错误,用于保存另一个向量的迭代器的向量
- C++,弹出调试断言失败窗口,我得到矢量迭代器不兼容的错误运行时
- 在 leveldb 的 c++ 示例中声明迭代器时出现分段错误
- std::map 擦除 - 将迭代器传递给错误的映射
- C++向量迭代器nth_element编译错误
- 如何修复错误,迭代器未在此范围内声明,并且迭代器未命名类型'
- 如何修复使用矢量和迭代器打印值的错误
- C++ 迭代器错误"does not refer to a value"
- 使用 -std=c++0x 会导致错误:“迭代器”未命名类型错误