统一与遗留初始化产生不同的编译结果

Uniform vs legacy initialisation producing different compilation results

我在用一段简单的代码排列时发现了这一点:

struct Base0 {};
struct Base1 {};

template<typename... Ts>
struct Derived: Ts... {};

int main() {
    Derived<Base0, Base1> d0 {Base0{}, Base1{}}; // OK
    Derived<Base0, Base1> d1 (Base0{}, Base1{}); // ERROR
}

我认为 d0d1 都应该导致编译错误,因为我看不出 Derived 没有任何匹配的 ctor 如何将 ctor 参数作为传递并标记 d0的编译没问题。

我可能缺少一些明显的东西。使它通过的统一初始化是什么?是聚合初始化还是什么?传递给 ctor 的临时对象发生了什么?

Using C++17 online compiler here

编辑

根据要求,我提供了喷出的复制粘贴:

main.cpp: In function ‘int main()’:
main.cpp:9:47: error: no matching function for call to ‘Derived::Derived(Base0, Base1)’
     Derived<Base0, Base1> d1 (Base0{}, Base1{}); // ERROR
                                               ^
main.cpp:5:8: note: candidate: constexpr Derived::Derived()
 struct Derived: Ts... {};
        ^~~~~~~
main.cpp:5:8: note:   candidate expects 0 arguments, 2 provided
main.cpp:5:8: note: candidate: constexpr Derived::Derived(const Derived&)
main.cpp:5:8: note:   candidate expects 1 argument, 2 provided
main.cpp:5:8: note: candidate: constexpr Derived::Derived(Derived&&)
main.cpp:5:8: note:   candidate expects 1 argument, 2 provided

看起来这是 aggregate initialisation 的新 C++17 功能:

Each direct public base, (since C++17) array element, or non-static class member, in order of array subscript/appearance in the class definition, is copy-initialized from the corresponding clause of the initializer list.

随着 class 与基数的变化现在可能是聚合(只要它们不是 virtualprivateprotected...尽管它们甚至不需要聚合!)。

你的失败案例没有使用聚合初始化,而是尝试了一个很好的老式构造函数调用。如您所见,不存在这样的构造函数。