首页 > 解决方案 > 统一与传统初始化产生不同的编译结果

问题描述

我在用一段微不足道的代码置换时注意到了这一点:

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 参数作为传递并且 flagsd0的编译很好。

我可能缺少一些明显的东西。使它通过的统一初始化是什么?是聚合初始化还是什么?传递给 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

标签: c++c++17uniform-initialization

解决方案


看起来这是聚合初始化的新 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.

It comes with the change that a class with bases may now be an aggregate (as long as they are not virtual, private, or protected… though they don't even need to be aggregates! ).

Your failing case does not use aggregate initialisation, but instead attempts a good old-fashioned constructor invocation. As you've identified, no such constructor exists.


推荐阅读