Variadic class 模板和继承 - 默认编译器生成的构造函数
Variadic class template and inheritance - default compiler generated constructor
下面的代码为什么只使用默认编译器生成的构造函数?
我希望它用于 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++ 周刊第 49/50 期的跟进,他在其中用 std::forward<T>(t)...
定义了一个可变参数构造函数
这里没有构造函数在起作用。由于 C++17 中的三个新功能的融合,此代码有效:
这一行发生了什么:
C c { []{}, [](int){} };
就是首先,我们通过模板参数推导(1)推导出c
确实是C<__lambda1, __lambda2>
类型。这是通过使用您的 演绎指南 完成的。
接下来,由于 C<__lambda1, __lambda2>
是一个聚合(由于 (2) 放宽了基础 class 限制 - 你是正确的,在 C++11/14 中不被视为聚合), 我们可以使用 aggregate-initialization 来初始化它。我们不使用构造函数。聚合初始化现在使用 base classes 的方式是我们只需要从左到右初始化基数。所以第一个表达式([]{}
)用于初始化第一个基数class(__lambda1
),第二个表达式([](int){}
)用于初始化第二个基数class(__lambda2
)。
最后,调用 c(3)
有效,因为 (3) 允许您简单地编写
using T::operator()...;
将两个 lambda 的调用运算符引入 C
的范围,其中重载解析可以按预期工作。结果是我们调用 __lambda2
的调用运算符,它什么也不做。
下面的代码为什么只使用默认编译器生成的构造函数? 我希望它用于 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++ 周刊第 49/50 期的跟进,他在其中用 std::forward<T>(t)...
这里没有构造函数在起作用。由于 C++17 中的三个新功能的融合,此代码有效:
这一行发生了什么:
C c { []{}, [](int){} };
就是首先,我们通过模板参数推导(1)推导出c
确实是C<__lambda1, __lambda2>
类型。这是通过使用您的 演绎指南 完成的。
接下来,由于 C<__lambda1, __lambda2>
是一个聚合(由于 (2) 放宽了基础 class 限制 - 你是正确的,在 C++11/14 中不被视为聚合), 我们可以使用 aggregate-initialization 来初始化它。我们不使用构造函数。聚合初始化现在使用 base classes 的方式是我们只需要从左到右初始化基数。所以第一个表达式([]{}
)用于初始化第一个基数class(__lambda1
),第二个表达式([](int){}
)用于初始化第二个基数class(__lambda2
)。
最后,调用 c(3)
有效,因为 (3) 允许您简单地编写
using T::operator()...;
将两个 lambda 的调用运算符引入 C
的范围,其中重载解析可以按预期工作。结果是我们调用 __lambda2
的调用运算符,它什么也不做。