c++ - 从 friend 类继承时无法使用大括号括起来的初始值设定项列表

标签 c++ c++11 inheritance initialization-list friend-class

我正在尝试为从其父类的子类继承的数据结构使用初始化列表。 下面我编译了一个演示问题的示例(在 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 '<brace-enclosed initializer list>' to i_gossip::i_am_secret secret .可以通过这样寻址和设置结构的每个独立成员来编译程序:

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

如果成员可用,为什么初始化列表会因编译错误而失败?

最佳答案

这两行并不等同,尽管它们都出现了相同的标识符。这个

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

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

另一方面,这条线

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,其中允许聚合具有公共(public)基类。

关于c++ - 从 friend 类继承时无法使用大括号括起来的初始值设定项列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57989127/

相关文章:

c# - SendMessage 中的误导参数类型 (... IntPtr wParam ...)

c++ - 当 return 语句、逗号运算符、花括号初始化列表和 std::unique_ptr 组合在一起时

c++ - C++ 中的重载赋值和圆括号运算符

c++ - 不要打印尾随定界符 stream_iterator C++

c++ - 打印出存储在具有相同祖先的不同类的变量中的值

Java "trick", 重新定义子类成员

c++ - 重命名(别名)数组元素 C

c++ - 从 C 文件调用 C++ 函数会出现 "undefined reference"编译器错误

c++ - 为什么我不能按值将右值 std::stringstream 传递给函数?

CSS继承: Override an ID parent selector with a CLASS child