经过多年的AS3,我正在尝试重新学习C ++。参考文献仍然适合我。
考虑以下功能:
#include <cstdio>
#include <list>
void f(std::list<int>& v) {
for (std::list<int>::iterator i = v.begin(); i != v.end(); ++i)
printf("Hello %d\n", *i);
}
std::list<int> get(void) {
std::list<int> list;
list.push_back(0);
return list;
}
现在,执行以下操作:
std::list<int> l = get();
f(l);
很好,但f(get())
会产生以下错误:
“没有匹配函数来调用'f'”,“候选函数不可行:没有已知的转换来自`'std :: list&lt; int&gt;'到'std :: list&lt; int&gt;&amp;'第一个参数“
为什么?是因为函数的结果是不可见的const
?
答案 0 :(得分:8)
执行此操作时:
f(get());
您将临时std::list<int>
传递给f()
。临时无法绑定到非const引用。因此,您可以通过传递const
引用来解决此问题,因为您不想修改参数。
void f(const std::list<int>& v)
{ // ^^^^^
for (std::list<int>::const_iterator i = v.begin(); i != v.end(); ++i)
{ // ^^^^^^^^^^^^^^
printf("Hello %d\n", *i);
}
}
请注意,这需要您使用const_iterator
,因为std::list::begin() const
和相应的end()
方法返回const_iterator
。在C ++ 11中,您可以将其简化为
for (auto i = v.begin(); i != v.end(); ++i)
...
甚至
for (const auto& i : v)
std::cout << i << "\n";
答案 1 :(得分:0)
您正在从std::list
方法返回一个临时get()
变量。这不起作用,因为您的参数不是const
来运行f
。
答案 2 :(得分:-1)
那是因为你的论点是T&amp;。它是T cont&amp;,它运作良好。
一些旧编译器使您的版本作为扩展 - 规则有点武断,并且可以避免意外。 T&安培; arg表示OUT(或INOUT)类型,如果修改以临时结束,则会出人意料。