5

经过多年的 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<int>' 到 'std::list<int>&' 的已知转换”

这是为什么?是因为函数的结果是不可见的const吗?

4

3 回答 3

8

当你这样做时:

f(get());

你传递一个临时std::list<int>f()。临时不能绑定到非常量引用。因此,您可以通过传递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);
  }
}

请注意,这要求您使用 a const_iterator, sincestd::list::begin() const和相应的end()方法 return const_iterators。在 C++11 中,您可以将其简化为

for (auto i = v.begin(); i != v.end(); ++i)
  ...

甚至

for (const auto& i : v)
  std::cout << i << "\n";
于 2013-06-18T16:31:37.350 回答
0

您正在从该方法返回一个临时std::list变量。get()这不起作用,因为您的论点不是constfunction f

于 2013-06-18T16:33:23.603 回答
-1

那是因为你的论点是 T&。它是 T cont&,它工作得很好。

一些旧的编译器让你的版本作为扩展工作——这个规则有点武断,是为了避免意外。T& arg 表示 OUT(或 INOUT)类型,如果修改最终是临时的,这是一个惊喜。

于 2013-06-18T16:32:23.510 回答