这个问题与数组初始化和SystemC模块层次结构有关。
我有一个不可复制,不可移动,没有默认构造函数的类:
class Object : public sc_module {
public:
Object(string name, Configuration config);
Object(const CPU& that) = delete;
};
和另一个包含这些数组的类:
class Object2 : public sc_module {
public:
std::array<Object, 2> obj_array;
Object2() : obj_array <--??-->
{}
};
我需要使用obj_array
初始化Objects
,该class Object2: {
public:
std::array<Object, 2> obj_array;
//note the double braces on this initializer list
Object2() : obj_array {{ {"string1", config}, {"string2", config} }}
{}
};
无法复制且无法移动。
我尝试了很多组合,编译的一件事就是:
Objects
它有效,但我在代码中看到了一些奇怪的行为:当我在obj_array
中打印出Object2.string1
的名称时,第一个是正确的Object2.string1.string2
但是当它应该只是Object2.string2
)时,下一个真的很奇怪arr
。
我知道很多人都提出了类似的问题,但我正在试图弄明白这里到底发生了什么。在我看来,我在初始化程序列表中有一个太多的括号,但它不会编译。否则就会编译。
使用g ++ 6.4.0和标志-std = c ++ 14
问题是如果我在构造函数的主体中创建另一个数组,例如 class Object2:{ 上市: std :: array obj_array; //记下此初始值设定项列表中的双括号 Object2():obj_array {{{“string1”,config},{“string2”,config}}} { Obj arr [2] {{“test”,config},{“test2”,config}}; } };
一切都好看。 .show.react-bs-table-sizePerPage-dropdown ul:last-child {
display: block;
}
对象名称和父母一样正确。
我知道这是一个深奥的问题,但我需要帮助了解我在obj_array初始化期间究竟发生了什么机制。
答案 0 :(得分:3)
带有双括号的表单是初始化std::array
的“完整”方式,因为std::array
实际上是一个包含原始C样式数组的聚合结构。它基本上是
namespace std {
template <class T, size_t N>
struct array {
T __some_internal_name[N];
// public members...
};
}
初始化如下:
std::array<int, 3> A{{ 2, 3, 4 }};
是有效的,因为外部{}
用于std::array
struct对象,而内部{}
用于它包含的原始C样式数组。
但是通常是,你不需要加倍括号,因为有一条规则允许你在另一个聚合中省略聚合的一些嵌套大括号。这就是初始化的原因:
std::array<int, 3> A{ 2, 3, 4 };
与上述相同。
规则是,当编译器将初始化列表的各个部分与聚合的子对象(结构/类的非静态数据成员或数组元素)关联时,如果下一个子对象也是聚合(包含至少一个自己的子对象)并且初始化列表的下一部分不以{
标记开头,然后子对象从初始化列表中获取尽可能多的部分,因为它具有自己的直接子对象。但是如果初始化列表中的下一个内容以{
开头,则假定它是该聚合子对象的完整初始化列表。
所以如果你有几乎正确的代码
Object2() : obj_array { {"string1", config}, {"string2", config} }
{}
编译器处理它是这样的:
obj_array
是一个std::array<Object, 2>
,它是一个聚合结构,它的初始化程序是一个支撑初始化列表,因此聚合初始化适用。
第一个{
与obj_array
对象相关联。
obj_array
有一个Object[2]
类型的子对象。此类型也是聚合类型,初始化列表中的下一个内容以{
开头,因此它会打开另一个初始化列表,用于初始化Object[2]
数组。
Object[2]
包含两个类型为Object
的子对象,它们是非聚合类类型。
第一个Object
必须使用初始化列表中的下一个内容进行初始化,即"string1"
。但是没有从const char[8]
到Object
的有效转换。这是一个错误。
之后可能会出现其他错误,具体取决于编译器尝试继续的方式。
简而言之,std::array
的单括号样式在您的情况下不起作用的原因是因为您打算成为Object
初始值设定项的开头是{
,它被视为C风格数组的初始化器。
双括号解决方案有效,或者您也可以指定Object
类型以避免使用另一个初始化列表启动初始化列表元素:
Object2() : obj_array { Object{"string1", config}, Object{"string2", config} }
{}
你的SystemC问题不太可能与所有这些有关,因为双支撑样式是正确的,并且会做你期望的。它可能是Configuration
类的详细信息。 (请注意,您的构造函数使用Configuration
参数“by value”,这意味着构造函数获取的对象将是您传递给它的任何内容的副本,如果这很重要。)我建议单独提出一个问题有关该问题的详细信息。