无法聚合初始化类型结构的变量与包含在类模板中的位字段成员

时间:2017-12-23 02:11:04

标签: c++ c++11

TrafficStats.setThreadStatsTag(ADS_THREAD_ID);

final AdRequest adRequest = new AdRequest.Builder()
    .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
    .addTestDevice(parent.getString(R.string.test_device_id))
    .build();

在参数列表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}; 错误的情况下,我没有得到构造函数匹配的实例。

这是编译器错误吗?我的bitfield结构符合聚合初始化的条件。

然后当我尝试聚合初始化包含数组成员的(int, int, int, int)派生结构时,虽然定义了匹配的构造函数,但我得到了类似的错误。

EndianGuard_

2 个答案:

答案 0 :(得分:1)

EndianGuarded_不是聚合。聚合没有构造函数,这种类型有构造函数。因此,列表初始化语法将尝试根据您提供的参数调用构造函数。

另外,即使你抛弃了构造函数,EndianGuarded_仍然不会是17之前的C ++规则的聚合。为什么?因为聚合不能有基类,而你的基类也不行。

即使这是C ++ 17,EndianGuarded_也没有4个子对象。它有2个;基类EndianGuard_和成员子对象Value_。所以你需要初始化它就像{{/*whatever goes to the base class}, {7, 6, 1, 0}}

答案 1 :(得分:1)

您的示例中缺少

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。