为什么下面的代码只使用默认的编译器生成的构造函数? 我希望它用于 POD,但下面的结构可能不是 POD,所以它一定是别的东西。
template <typename ... T>
struct C : T ... {
using T::operator()...;
};
// template class guidance feature of C++17
template <typename ... T>
C(T...) -> C<T...>;
int main(){
C c { []{}, [](int){} };
c(3);
}
这个问题是 Jason 的 Turner C++ 周刊 ep 49/50 的后续,他在其中用 std::forward<T>(t)...
定义了一个可变参数构造函数。
最佳答案
这里没有构造函数在起作用。由于 C++17 中的三个新功能的融合,此代码有效:
这一行发生了什么:
C c { []{}, [](int){} };
首先,我们使用模板参数推导(1)来推导c
确实是 C<__lambda1, __lambda2>
类型.这是通过使用您的演绎指南来完成的。
接下来,自 C<__lambda1, __lambda2>
是聚合(由于 (2) 放宽了基类限制 - 你是正确的,在 C++11/14 中不被视为聚合),我们可以使用 aggregate-initialization 来初始化它。我们不使用构造函数。聚合初始化现在使用基类的方式是我们只需要从左到右初始化基类。所以第一个表达式([]{}
)用于初始化第一个基类(__lambda1
),第二个表达式([](int){}
)用于初始化第二个基类(__lambda2
)。
最后,调用c(3)
之所以有效,是因为 (3) 允许您简单地编写
using T::operator()...;
这将两个 lambda 的调用运算符都引入了 C
的范围内,其中重载解析可以按预期工作。结果是我们调用__lambda2
的调用运营商,什么都不做。
关于c++ - Variadic 类模板和继承 - 默认编译器生成的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44036076/