无法汇总初始化类型结构的变量,其中包含在类模板中的位字段成员

unable to aggregate initialise a variable of type structure with bit field members wrapped in class template

本文关键字:包含 成员 字段 初始化 类型 变量 结构      更新时间:2023-10-16
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的初始化可以说是最可读的,因为它隐含地表明您正在调用一个参数(outer ())的构造函数,并且该构造函数采用汇总的启动构造struct(Inner {})。

SlotZ初始化使用隐式类型转换。标记构造函数explicit,它将失败。Google C 样式需要一个单词的构造函数,以标记explicit,因为它们可能会引起这样的惊喜。但是ymmv。