使用容器的for循环语法-是否会生成副本?

4

我正在学习新的C++11语法,用于遍历STL容器。到目前为止,我遇到了以下示例:

std::vector<int> plus;
....
for(int l : plus)
{
std::cout << l;
}     

我的问题是,上面的语法是否会复制int类型的数据?如果是,那么这种做法不是更有效率吗?
for(int& l : plus)

1
通常来说,对于int和其他小类型,引用比拷贝略微低效。但是,放入不必要的引用并不会有太大影响。 - chris
如果在循环内部使用“l”的值,例如输出它,那么它将被复制。从任何角度来看,第一个循环更有效率(如果您从未利用引用语义,则可以将循环2优化为它)。 - molbdnilo
3个回答

8

从语义上讲,它会创建一个副本,尽管对于内置类型可能没有效率问题,实际上使用副本甚至可能更便宜。但是如果您拥有昂贵的对象需要复制,则最好在循环中使用const引用。

std::vector<ExpensiveToCopy> v;
for (const auto& i : v)
  std::cout << i << std::endl;

如果您想改变对象,只应该使用非const引用。


5

是的,如果你没有明确表示需要一个引用,你会得到一份副本。对于内置类型而言,复制实际上比引用更为高效 - 当然,除非你需要引用的语义。


2

对于向量中的每个元素,它都会调用复制构造函数。如果你使用const 引用,它根本不会调用任何构造函数。如果你不打算修改元素,应该使用const。例如:

class Test
{
public:
    Test() { std::cout << "Default.\n"; }
    ~Test() { }
    Test(const Test& other) { std::cout << "Copy.\n"; }
    Test(Test&& other) { std::cout << "Move.\n"; }
};

int main()
{
    std::vector<Test> test;
    test.emplace_back(Test());
    for (const Test& t : test)
    {
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接