c++ - Variadic 类模板和继承 - 默认编译器生成的构造函数

标签 c++ c++17

为什么下面的代码只使用默认的编译器生成的构造函数? 我希望它用于 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 中的三个新功能的融合,此代码有效:

  1. 构造函数的模板参数推导(P0091)。
  2. 扩展聚合初始化(P0017)
  3. 现代化使用声明 ( P0195 )。

这一行发生了什么:

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/

相关文章:

c++ - 是什么让两个数组映射到同一个缓存行?

c++ - 无法使用 `std::make_shared` 分配指针

c++ - 动态数组与 std::vector

c++ - 创建变体交替值和值数组

c++ - 动态可转换类型特征

C++ 库和自注册类 : Factory map empty in client application

c++ - 如何在另一个程序中使用在一个程序中声明的变量?

c++ - 可以单独声明函数数组的元素吗?

c++ - 如何在 c++17 中传递 Callable 对象以与 std::invoke 一起使用

c++ - 奇怪的 basic_string 构造函数 c++17