统一与遗留初始化产生不同的编译结果
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
}
我认为 d0
和 d1
都应该导致编译错误,因为我看不出 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 与基数的变化现在可能是聚合(只要它们不是 virtual
、private
或 protected
...尽管它们甚至不需要聚合!)。
你的失败案例没有使用聚合初始化,而是尝试了一个很好的老式构造函数调用。如您所见,不存在这样的构造函数。
我在用一段简单的代码排列时发现了这一点:
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
}
我认为 d0
和 d1
都应该导致编译错误,因为我看不出 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 与基数的变化现在可能是聚合(只要它们不是 virtual
、private
或 protected
...尽管它们甚至不需要聚合!)。
你的失败案例没有使用聚合初始化,而是尝试了一个很好的老式构造函数调用。如您所见,不存在这样的构造函数。