Битовые поля "инициализация в классе" приводят к " ошибке: lvalue требуется как левый операнд назначения"
struct bitfield {
int i = 0; // ok
int j : 8 = 0; // error: lvalue required as left operand of assignment
};
каков правильный синтаксис для инициализации битовых полей с помощью функции C++11 "инициализация в классе"?
4 ответов
каков правильный синтаксис для инициализации битовых полей с помощью функции C++11 "инициализация в классе"?
вы не можете инициализировать битовые поля в классе. В пункте 9.2 стандарта C++11 указывается грамматика для деклараторов членов класса:
[...]
член-Декларатор:
Декларатор virt-спецификатор-seq(opt) pure-спецификатор (opt)
Декларатор скобка-или-равный-инициализатор (opt)
идентификатор(opt) атрибут-спецификатор-seq (opt): константа-выражение
Как вы можете видеть, деклараторы для членов битового поля не могут быть завершены brace-or-equal-initializer.
Это было поднято как основной вопрос 1341 к стандарту C++, но было отклонено основной рабочей группой C++ в октябре 2015 года как NAD ("не дефект") - см. http://open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1341
Вы можете написать конструктор со списком инициализации, дает значения по умолчанию для полей.
struct bitfield {
int i;
int j : 8;
bitfield() : i(0), j(0) {};
};
вы также можете создавать поля только для чтения со значениями по умолчанию.
struct _UserRegister1
{
uint8_t _RES0 : 1;
const uint8_t reserved1 : 1;
uint8_t _HTRE : 1;
const uint8_t reserved2 : 3;
uint8_t _VDDS : 1;
uint8_t _RES1 : 1;
_UserRegister1() : reserved1(1), reserved2(7) {};
};
вы не можете (в C++11) в классе инициализировать bitfields.
в MSVC и gcc (с расширениями) анонимный union
и struct
код позволяет обойти это немного.
struct bitfield {
int i = 0; // ok
union {
uint32_t raw = 0;
struct {
int j : 8;
int x : 3;
};
};
};
где мы смешиваем фиксированный размер raw
С union
над битовыми полями, затем в классе инициализируйте raw
элемент.