从朋友类继承时无法使用大括号括起来的初始化列表

Posted

技术标签:

【中文标题】从朋友类继承时无法使用大括号括起来的初始化列表【英文标题】:Unable to use brace enclosed initializer-list while inheriting from friend class 【发布时间】:2019-09-18 09:12:06 【问题描述】:

我正在尝试为从其父朋友类的子类继承的数据结构使用初始化列表。 下面我编译了一个演示问题的示例(在 c++11 中)。

#include <iostream>
#include <vector>

class i_gossip;

class i_have_secrets
    friend class i_gossip;
public:
    i_have_secrets();
private:
    struct secret_t
        int secret_number;
        std::vector<int> secret_vector;
    i_am_secret;
;

class i_gossip
public:
    struct i_am_secret : public i_have_secrets::secret_t  ;
;

i_have_secrets::i_have_secrets()
    i_am_secret = 0, 0,1,2; // Totally fine


int main(int argc,char** args)
    i_gossip::i_am_secret secret = 0, 0,1,2; // Compile error
    return 0;


声明很好,但初始化不是,它给出了错误could not convert ... from '&lt;brace-enclosed initializer list&gt;' to i_gossip::i_am_secret secret。可以通过这样处理和设置结构的每个单独成员来编译程序:

    i_gossip::i_am_secret secret;
    secret.secret_number = 0;
    secret.secret_vector = 0,1,2;

如果成员可以使用,为什么初始化列表会失败并出现编译错误?

【问题讨论】:

不能用 clang++(只给我一个警告,建议另一个大括号级别,i_gossip::i_am_secret secret = 0, 0,1,2;)和 g++(没有错误也没有警告)复制。你用的是哪个编译器? gcc 版本 9.2.0(Rev2,由 MSYS2 项目构建)与 -std=c++11 对不起:我已经编译了 C++17;是的:使用 C++11 和 C++14 我重现了你的错误。 【参考方案1】:

尽管两行出现相同的标识符,但这两行并不等价。这个

i_have_secrets::i_have_secrets()
    i_am_secret = 0, 0,1,2; // Totally fine

分配给类型为secret_t成员变量。碰巧secret_t 是 C++11 中的聚合,所以它的作用是执行分配给 i_have_secrets::i_am_secret 的临时 secret_t 的 aggregate initialization。

另一方面,这条线

int main(int argc,char** args)
    i_gossip::i_am_secret secret = 0, 0,1,2; // Compile error
    return 0;

尝试初始化i_gossip::i_am_secret(不是secret_t)类型的对象。在 C++11 中,具有任何基类的类不是聚合。所以尝试通过聚合初始化来初始化非聚合是行不通的。

您可以使用类型别名而不是派生类

class i_gossip
public:
    using i_am_secret = i_have_secrets::secret_t;
;

这将暴露内部类型、聚合初始化和所有内容。

或者,您可以切换到 C++17,其中允许聚合具有公共基类。

【讨论】:

以上是关于从朋友类继承时无法使用大括号括起来的初始化列表的主要内容,如果未能解决你的问题,请参考以下文章

无法从大括号括起来的初始化列表转换

C ++类成员函数别名模板,防止大括号括起来的初始化程序列表被识别为对/元组

类大括号括起来的初始化列表失败

大括号括起来的初始值设定项列表转换错误

数组必须用大括号括起来的初始化程序 c++ 初始化

大括号之谜:C++的列表初始化语法解析