我正在尝试为从其父类的子类继承的数据结构使用初始化列表。 下面我编译了一个演示问题的示例(在 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/