struct EndianGuard_ {};
template<typename Type_>
struct EndianGuarded_ : EndianGuard_ {
EndianGuarded_() {
uint8_t* ByteData = (uint8_t*) this;
for (int i = 0; i < sizeof (Type_); i++) {
ByteData[i] = 0;
}
};
EndianGuarded_ (Type_ Value) : Value (Value) {};
~EndianGuarded_ () {};
Type_ Value;
};
struct Slot_2 {
uint8_t Slot : 4;
uint8_t Unit : 3;
uint8_t Bus : 2;
uint8_t Unused : 7;
};
EndianGuarded_<Slot_2> Slot = {7, 6, 1, 0};
给定参数列表(int, int, int, int)
错误,我没有得到构造函数匹配的实例。
这是编译器错误吗?我的bitfield结构符合聚合初始化条件。
然后当我尝试聚合初始化包含数组成员的EndianGuard_
派生结构时,虽然定义了匹配的构造函数,但我得到了类似的错误。
struct ProtocolResult_ : EndianGuard_ {
ProtocolResult_(const EndianGuarded_<char> Value[2]) {
this->Value[0] = Value[0];
this->Value[1] = Value[1];
};
static const ProtocolResult_
NORMAL_ANSWER,
BUSY;
EndianGuarded_<char> Value[2];
};
const ProtocolResult_ ProtocolResult_:: // no matching constructor with arguments
NORMAL_ANSWER = {{'0', '0' }}, // ({...})
BUSY = { '1', '1' }; // (char, char)
EndianGuarded_
不是一个总和。聚合没有构造函数,这种类型有构造函数。因此,列表初始化语法将尝试根据您提供的参数调用构造函数。
另外,即使你抛弃了构造函数,EndianGuarded_
在17之前仍然不会是C ++规则的聚合。为什么呢?因为聚合不能有基类,而你的基类也不行。
即使这是C ++ 17,EndianGuarded_
也没有4个子对象。它有2个;基类EndianGuard_
和成员子对象Value_
。所以你需要初始化它就像{{/*whatever goes to the base class}, {7, 6, 1, 0}}
。
您的示例中缺少EndianGuard_
定义,因此我将其添加为空结构。以下三个初始化中的每一个都将使用C ++ 11进行编译:
struct EndianGuard_ { };
template<typename Type_>
struct EndianGuarded_ : EndianGuard_ {
EndianGuarded_ (Type_ Value) : Value (Value) {};
private:
Type_ Value;
};
struct Slot_2 {
int Slot : 4;
int Unit : 3;
int Bus : 2;
int Unused : 7;
};
EndianGuarded_<Slot_2> SlotX = {{7, 6, 1, 0}};
EndianGuarded_<Slot_2> SlotY({7, 6, 1, 0});
EndianGuarded_<Slot_2> SlotZ = Slot_2 {7, 6, 1, 0};
SlotY
的初始化可以说是最具可读性的,因为它隐式显示你正在调用带有一个参数的构造函数(外部()
),并且这个构造函数采用聚合初始化结构(内部{}
)。
SlotZ
初始化使用隐式类型转换。标记构造函数explicit
,它会失败。例如,Google C ++风格要求将单参数构造函数标记为explicit
,因为它们可能会导致像这样的惊喜。但是YMMV。