为什么初始化列表会产生 2 个数据副本,而不仅仅是将一个副本传递给函数?

Why does an initializer list cause 2 copies of data and not just the a single copy to pass it to the function?

如果我们创建一个简单的 dummy-class 如下:

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。这意味着你有原始对象,你的列表有一个对象的副本,你的函数有一个 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});
}

第二个副本与初始化列表本身无关。当您迭代列表 "by value"

时,第二个副本在您的 some_function 中创建
for (example exam : input) {
    std::cout << &exam << std::endl;
}

如果你重复它 "by const reference" 而不是第二个副本将消失。