为什么初始化列表会导致2个数据副本而不仅仅是单个副本将其传递给函数?

时间:2017-09-06 18:56:52

标签: c++ c++11 initializer-list

如果我们按如下方式创建一个简单的虚拟类:

struct example {
    example() { std::cout << "Create" << std::endl; }
    example(const exam&) { std::cout << "Copy" << std::endl; }
    example(example &&) noexcept { std::cout << "Move" << std::endl; }
}

并将其传递给初始化列表(std::initializer_list<example>):

some_function({example()});

输出(来自GCC / C ++ 11)是:

Create
Copy
Copy

在创建示例对象本身然后将​​其传递给initializer_list时,这对我没有意义。这意味着你有原始对象,你的列表有一个对象的副本,你的函数有一个列表(不是示例对象)的副本,暗示它应该是你对象的单个创建然后是初始化列表的单个副本。

预期输出(没有额外的副本):

Create (from example())
Copy (into initializer_list)

TL; DR:为什么传递我的对象通过初始化列表实例化对象的两个副本而不是一个副本如果对象在初始化列表本身中传递?

#include <iostream>
#include <initializer_list>

struct example {
    example() { std::cout << "Create" << std::endl; }
    example(const example &) { std::cout << "Copy" << std::endl; }
    example(example &&) noexcept { std::cout << "Move" << std::endl; }
};

void some_function(std::initializer_list<example> input) {
    for (example exam : input) {
        std::cout << &exam << std::endl;
    }
}

int main()
{
    example exam;
    some_function({exam});
}

1 个答案:

答案 0 :(得分:4)

第二个副本与初始化列表本身无关。当您迭代列表时,第二个副本会在您的some_function内创建&#34;按值&#34;

for (example exam : input) {
    std::cout << &exam << std::endl;
}

如果你通过const引用迭代它&#34;&#34;相反,第二个副本将消失。