【问题标题】:Why is C++ brace initialization not supported for aggregates with private members?为什么具有私有成员的聚合不支持 C++ 大括号初始化?
【发布时间】:2018-01-25 02:13:45
【问题描述】:

在我看来,从概念上讲,以下内容不会侵犯隐私。但这是被禁止的。

struct A
{
        int a;
        int b;
        int c;
};
struct B
{
        int a;
        int b;
private:
        int c;
};

int main (int argc, char * argv[])
{
        auto a = A{1,2,3}; //ok
        auto b = A{1,2};   //ok
        auto c = B{1,2,3}; //error
        auto d = B{1,2};   //error
        return 0;
}

添加手动构造函数将允许对私有成员进行大括号初始化。但是聚合和 pod 的美妙之处在于您需要的编码量很少,因此这很烦人。

另一方面,this is a privacy breach in my opinion 但这是标准允许的。

【问题讨论】:

  • 您不能对 struct B 使用聚合初始化,因为它不是聚合(聚合的所有非静态成员都必须是公共的)。
  • @Jerry,是的,我知道,这就是我要说的。但我也在抱怨它。为什么这个标准会使原本可以如此简单的事情变得复杂?
  • 你基本上是在问为什么类的非成员不能写私有变量。这是设计使然。链接的问题是一个极端情况,可以说是一个标准缺陷。
  • @GMan。为什么将大括号初始化视为非成员访问?对我来说,这有点类似于构造函数调用。这是一种新型的自动构造函数。
  • 目前的规则简单明了。如果您允许使用私有成员对某些内容进行聚合初始化,您将如何处理 class A { int a; public: int b; }; A a{1}; 之类的内容您使用 1 来初始化 A::a 还是 A::b?任何一种选择都会让相当多的人感到不安和/或困惑。

标签: c++ uniform-initialization list-initialization


【解决方案1】:

不存在具有私有或受保护的非静态数据成员的聚合。聚合的所有非静态数据成员都必须是公共的。

private:
    int c;

导致B 不再是聚合。因此聚合初始化不再起作用。

【讨论】:

  • 答案是正确的,我的问题不是因为我想知道标准为什么做出这个限制。
【解决方案2】:

我认为 Jerry Coffin 是对的。该类无权禁止其私有/受保护成员被初始化为来自客户端的任何值,或被其假设的“聚合初始化”取消初始化。

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-22
  • 2019-01-11
  • 1970-01-01
  • 2019-04-13
  • 1970-01-01
相关资源
最近更新 更多