Битовые поля "инициализация в классе" приводят к " ошибке: 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 элемент.