#include <iostream>
#include <type_traits>
using namespace std;
void f(string::iterator &it)
{
++it;
}
int main()
{
string s="123456";
f(s.begin());//这行出错,
return 0;
}
[Error] invalid initialization of non-const reference of type 'std::basic_string<char>::iterator& {aka __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&}' from an rvalue of type 'std::basic_string<char>::iterator {aka __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >}'
[Note] in passing argument 1 of 'void f(std::basic_string<char>::iterator&)'
我百度的原因说是因为s.begin()返回的iterator带const,把const属性去掉即可。https://blog.
在STL中,我们能见到很多函数的形参都是iterator的传值,而不是传引用。
这是因为我们通常这么用:
void print_vector(vector<int>::iterator beg, vector<int>::itertor end);
while(beg != end) { cout << *beg++ << endl; }
print_vector(v.begin(), v.end());
这里形参如果是引用的话,则编译时会报错,因为v.begin()返回的是一个临时变量,是一个右值,它不能赋值给一个非const的引用:
error: invalid initialization of non-const reference of type 'std::vector<int>::iterator& {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >&}' from an rvalue of type 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}'
但可以赋值给const 引用;即如果print_vector的形参是const的iterator,就可以传v.begin()给它。但这样一来,在函数体内就不能做++,--或任何修改该iterator的操作了。
这就是iterator一般用传值的原因。
类似的道理,函数的返回值通常不能传给一个非const的引用,因为函数返回值通常也是一个临时变量,是一个右值。
int f() { return 1; }
int &ri1 = f(); //error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'
const int &ri2 = f(); // OK