统一与旧式初始化会产生不同的编译结果

ust*_*ion 7 c++ uniform-initialization c++17

我在用一些琐碎的代码排列时就注意到了这一点:

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
}
Run Code Online (Sandbox Code Playgroud)

我认为两者d0d1应导致编译错误,因为我看不出Derived没有任何匹配的构造函数需要构造函数参数如通过和标志d0的编译细。

我可能想念一些明显的东西。使它通过的统一初始化是什么?是聚合初始化还是什么?临时人员传给ctor的情况如何?

在此处使用C ++ 17在线编译器

编辑

根据要求,我提供了喷出的副本粘贴:

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
Run Code Online (Sandbox Code Playgroud)

Lig*_*ica 10

看起来这是聚合初始化的 C ++ 17新功能:

从类定义中的数组下标/外观开始,每个直接的公共基础(自C ++ 17起)数组元素或非静态类成员都从初始化程序列表的相应子句中进行复制初始化。

它配备了变化,与基础类现在可能是集合(只要他们不是virtualprivate或者protected......虽然他们甚至不需要是聚集!)。

失败的案例不使用聚合初始化,而是尝试良好的老式构造函数调用。如您所知,不存在这样的构造函数。

  • 有趣的是,基础本身不一定是可用的集合。 (2认同)
  • @ustulation因为没有复制发生。C ++ 17保证它对“临时”使用初始化器,而不是直接初始化源。您不需要可访问的复制/移动构造函数即可工作。现在,这使我们能够为任何类型构建工厂函数,即使它们无法移动也无法复制。 (2认同)