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

问题描述:

如果我们创建一个简单的伪级,如下所示:为什么初始化程序列表会导致2个数据副本,而不仅仅是一个副本将其传递给该函数?

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}); 
} 
+3

发布您正在询问的完整,可编辑的示例。 –

+0

你怎么知道第二个副本来自'initializer_list'本身?什么是'some_function()'实际上对列表做了什么? “some_function()”甚至如何声明? –

+0

我将编辑并追加@NeilButterworth的示例。 –

第二个副本与初始化程序列表本身无关。您some_function内部创建的第二个副本,当你遍历列表“按值”

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

如果你迭代它“通过const引用”而非secondy副本将会消失。

+0

Bam。愚蠢的错误。谢谢! –

+0

我无法复制 - 我根本没有复制 - 只创建 –