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

标签 c++ list-initialization deleted-functions defaulted-functions

我对在 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);
};

因此,当我取消注释某些行组合(并使用带有 clang 的 c++17 标准标志进行编译)时,我对发生的情况感到困惑:

  • 1,编译。列出 AA1 的 init,以及 A2
  • 的默认复制构造函数
  • 2,编译。 A 和 list init A1(?) 的默认构造函数,以及 A2
  • 的默认复制构造函数
  • 1 + 3 或 2 + 3,由于删除了 A2 的复制构造函数而编译失败
  • 1 + 4,编译。 A 和 list init A1(?) 的默认构造函数,以及 A2
  • 的默认复制构造函数
  • 2 + 4,编译。 A 和 list init A1(?) 的默认构造函数,以及 A2
  • 的默认复制构造函数
  • 1 + 5,编译失败。说 A 缺少(删除)默认构造函数,并且 A1 没有匹配的构造函数?
  • 2 + 5,编译失败。 A1 没有匹配的构造函数?

我想我明白了其中的大部分内容,但我对 1 + 5 和 2 + 5 编译失败的原因感到困惑。谁能解释编译器用来选择它将要使用的构造函数的逻辑,以及编译失败的原因?

如果我认为在其他情况下调用的构造函数是错误的,您能否也指出调用的是什么,为什么调用?

最佳答案

1, Compiles. List init's for A and A1, and the default copy constructor for A2

在这种情况下,你所说的 List init 实际上是 aggregate initialization因为 StructTest 是一个集合。这是允许的,因为显式默认或删除的构造函数的存在仍然使该类成为聚合。

2, Compiles. Default constructor for A and list init A1?, and the default copy constructor for A2

A1 像 1 中发生的那样进行了聚合初始化。其余部分正确

1 + 3 or 2 + 3, Fails to compile because of the deleted copy constructor for A2

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

1 + 4, Compiles. Default constructor for A and list init A1?, and the default copy constructor for A2

同样,AA1 的聚合初始化

2 + 4, Compiles. Default constructor for A and list init A1?, and the default copy constructor for A2

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

1 + 5, Fails to compile. Says A is missing(deleted) a default constructor, and no matching constructor for A1?

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

2 + 5, Fails to compile. No matching constructor for A1?

与 1 + 5 相同的原因

关于C++11 删除/默认构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53640546/

相关文章:

c++ - 我可以使用成员变量实例化成员类模板吗?

C++ - Zlib - header 和无 header 支持。有多可靠?

c++ - 为什么在初始化此类时不调用列表初始化?

c++ - 复制复制者和复制分配的删除 - 公共(public)、私有(private)或 protected ?

c++11 - 通过删除析构函数来实现不可实例化的类?

c++ - 如何使用带有 std::initializer_list 的构造函数设计类?

C++ 模板元编程 : overloading operators

c++ - 默认参数和空列表初始化

c++ - 大括号初始化与括号错误