C++ 11删除/默认的构造函数

And*_*ndy 4 c++ defaulted-functions deleted-functions list-initialization

我对在C++ 11和C++ 17中如何/为什么调用构造函数感到困惑.

#include <iostream>
using namespace std;

//---

template<typename T>
struct StructTest
{
public:
  const T Var = -1;

  //---

  // constexpr StructTest() = delete;  // 1
  // constexpr StructTest() = default; // 2

  // constexpr StructTest(const StructTest &Source) = delete;                  // 3
  // constexpr StructTest(const StructTest &Source) = default;                 // 4
  // constexpr StructTest(const StructTest &Source) {cout << "Copy" << endl;}; // 5
};

//---

StructTest<int> A{};
StructTest<int> A1{1};
StructTest<int> A2(A);

//---

int main(void)
{
  return(0);
};
Run Code Online (Sandbox Code Playgroud)

所以当我取消注释某些行的组合(并使用带有clang的c ++ 17标准标志进行编译)时,我会感到困惑:

  • 1,编译.列出init的for AA1,以及默认的复制构造函数A2
  • 2,编译.默认构造函数用于A和列出init A1(?),以及A2的默认复制构造函数
  • 1 + 3或2 + 3,因为删除了复制构造函数而无法编译 A2
  • 1 + 4,编译.默认构造函数A和列表init A1(?),以及默认的复制构造函数A2
  • 2 + 4,编译.默认构造函数用于A和列出init A1(?),以及A2的默认复制构造函数
  • 1 + 5,无法编译.说A缺少(删除)默认构造函数,没有匹配的构造函数A1
  • 2 + 5,无法编译.没有匹配的构造函数A1

我想我理解大部分内容,但我很困惑为什么1 + 5和2 + 5编译失败.任何人都可以解释编译器用来选择它将要使用的构造函数的逻辑,以及它为什么无法编译?

如果我认为在其他情况下调用的构造函数是错误的,您是否还可以指出所调用的内容,为什么?

Nat*_*ica 9

1,编译.列出A和A1的init,以及A2的默认复制构造函数

在这种情况下,您所谓的List init实际上是聚合初始化,因为它StructTest是一个聚合.这是允许的,因为显式默认或删除的构造函数的存在仍然使该类成为聚合.

2,编译.A和列表init A1?的默认构造函数,以及A2的默认复制构造函数

A1 聚合初始化就像1中发生的那样.其余的都是正确的

1 + 3或2 + 3,由于删除了A2的复制构造函数,无法编译

这是预期的行为,因为复制构造函数被标记为已删除.

1 + 4,编译.A和列表init A1?的默认构造函数,以及A2的默认复制构造函数

同样,对于集合初始化AA1

2 + 4,编译.A和列表init A1?的默认构造函数,以及A2的默认复制构造函数

AA1将被聚合初始化,但它会使用的默认成员初始化Var初始化时A[dcl.init.aggr] /5.1

1 + 5,无法编译.说A缺少(删除)默认构造函数,而A1没有匹配的构造函数?

图5是用户提供的非默认或删除的构造函数.这意味着StructTest不再是聚合,您不能再聚合初始化它.

2 + 5,无法编译.没有匹配的A1构造函数?

与1 + 5相同的原因


M.M*_*M.M 5

(这是其他答案的附加信息)

对于C++ 11,C++ 14/17和C++ 20,此代码的行为是不同的!由于聚合的定义不断变化.

在C++ 11中,类不是聚合,因为它有一个大括号或者是相等的初始值(= -1),所以大小写1不能编译.

在C++ 14和17中,类是聚合,其他答案涵盖了这种情况.

在C++ 20中,类不会再次成为聚合,因为有一个新规则,任何用户声明的构造函数都不会使一个类成为聚合; 所以case 1将再次停止编译,并且在case 2中,StructTest<int> A1{1};由于构造函数的参数太多等原因,将无法编译.