std :: initializer_list是否具有复制构造函数,是否曾经使用过?

Poo*_*ria 2 c++ copy-constructor initializer-list c++14

std :: initializer_list是否具有复制构造函数,如果有,是否曾经使用过?在哪种情况下?因为我注意到以下内容无法在GCC中编译:

std::initializer_list<int>{{1,2,3,4}};
Run Code Online (Sandbox Code Playgroud)

而下面的一个

class Test{
    public:
        Test(const std::initializer_list<int> &){}
};
Test{{1,2,3,4,5,6}};
Run Code Online (Sandbox Code Playgroud)

所以我怀疑std :: initializer_list <int>是否具有Test类具有的构造函数,第一段代码将进行编译

Nic*_*las 5

所以我怀疑std :: initializer_list <int>是否具有Test类具有的构造函数,第一段代码将进行编译

那会假设“统一初始化”实际上是统一的,这总是一个危险的假设。

initializer_list has special rules about being constructed from a braced-init-list. If you apply a braced-init-list to an initializer_list<T>, then [dcl.init.list]/3.5 kicks in, which says go "below," skipping the remaining subparagraphs. And "below" says:

An object of type std?::?initializer_­list<E> is constructed from an initializer list as if the implementation generated and materialized a prvalue of type “array of N const E”, where N is the number of elements in the initializer list.

Well, you're constructing your initializer_list<int> from a single element, which itself is a braced-init-list. That braced-init-list now gets applied to E, which is int. And because that list has more than one entry, that doesn't work.

Because subparagraph 3.5 explicitly skipped all of the other subparagraphs in that section, it doesn't matter if that inner braced-init-list could create an initializer_list<int>. The compiler never checks for that, because the check to do that was in 3.6, which was skipped.


For the record, initializer_list does have (defaulted) copy/move constructors and assignment operators.

  • @Pooria:没有;它使用“复制列表初始化”,这是列表初始化的一种形式,不需要调用复制构造函数。 (2认同)