6

假设我有这个结构:

struct F
{
    int& ref; // reference member
    const int c; // const member
    // F::F() is implicitly defined as deleted
};

那是来自cppreference。正如我从文档中了解到的那样,构造函数F被认为是已删除,因为它有一个引用变量,它什么都没有引用。所以不能F像这样声明一个类型的变量:F variableName;因为会有错误,例如: struct 中的未初始化引用成员F

我理解这一点,但是如果您甚至不能声明其类型的变量,我不明白这样的结构有什么好处。这种数据类型在某些特定情况下有用吗?

4

2 回答 2

9

由于F是聚合,您可以使用聚合初始化

int a = 42;
F f1 = {a, 13};

// or

F f2{a, 9};

现场演示

一个类类型(通常是结构或联合)是一个聚合,如果它具有:

  • 没有私有或受保护的非静态数据成员
  • 没有用户提供的、继承的或显式的(C++17 起)构造函数(允许显式默认或删除的构造函数)(C++11 起)
  • 没有虚拟、私有或受保护 (C++17 起) 基类
  • 没有虚拟成员函数
于 2018-05-01T07:53:04.483 回答
6

我理解这一点,但是我不明白如果你甚至不能声明它的类型的变量,这种结构会有什么好处。这种数据类型在某些特定情况下有用吗?

被删除的隐式默认构造函数并不意味着你永远不能使用这种类型。这意味着您必须自己定义构造函数,因为只有您,程序员,才能知道该引用应该绑定到什么。所以编译器把它留给你,如果你忘记了,你会被通知 c'tor 被删除。

这就是它被删除的原因,但正如人们所提到的,这本身并不意味着您不能按原样使用该结构。仍然可以聚合初始化它(但是,如果它具有私有数据成员,则不可能,因此也需要考虑这一点)。

一个简单的用例可能是给成员取别名。例如(这是一个玩具示例,您可以改用默认成员初始化器):

struct Point {
  double coord[3];
  double& x;
  double& y;
  double& z;

  Point() : x(coord[0]), y(coord[1]), z(coord[2]) {}
};

引用成员还意味着您需要为其他成员函数提供定义以确保您的对象正确运行,因为它们使事情变得有些复杂。这就是为什么它们通常被避免。

其他用途无法真正详尽地列举。

于 2018-05-01T07:47:01.807 回答