Нестатический инициализатор члена от другого не статичного

Очень простой вопрос Это действительный C ++ 11?

struct Foo {
int bar = 1;
int baz = bar;
};

GCC (4.7.2) и Clang (3.1) принимают его с педантичными настройками:

-std = c ++ 11 -Wall -W -pedantic

Intel C ++ (13.0.1.117) этого не делает. Лает на int baz = bar; с:

ошибка: нестатическая ссылка на элемент должна относиться к конкретному объекту

Кто прав?

В случае, если вам интересно, я использую это для такого кода, где он сближает код инициализации, а не перемещает последнюю строку в конструктор:

uint8_t colorR = -1;
uint8_t colorG = -1;
uint8_t colorB = -1;
uint8_t colorA = -1;
GLubyte RGBAVec[4] = {colorR, colorG, colorB, colorA};

6

Решение

5.1p12 ID-выражение это обозначает нестатический член данных или нестатическая функция-член класса может только
использоваться:

  • как часть доступа к члену класса (5.2.5), в котором выражение объекта ссылается на класс члена
    или класс, производный от этого класса, или
  • сформировать указатель на член (5.3.1), или
  • в мем-инициализатор для конструктора для этого класса или для класса, производного от этого класса (12.6.2), или
  • в скобки или равно-инициализатор для нестатического члена данных этого класса или класса, полученного из этого
    класс (12.6.2) или
  • если это id-выражение обозначает нестатический элемент данных и появляется в неоцененном операнде.

Так что да, это:

struct Foo {
int bar = 1;
int baz = bar;
};

действителен C ++ 11.

Но будьте осторожны с порядком, потому что:

12.6.2p10 В не делегирующем конструкторе инициализация происходит в следующем порядке:

  • Во-первых, и только для конструктора самого производного класса (1.8), виртуальные базовые классы инициализируются в
    порядок, в котором они появляются на первом глубинном обходе слева направо направленного ациклического графа базовых классов,
    где «слева направо» — порядок появления базовых классов в списке базовых спецификаторов производного класса.
  • Затем прямые базовые классы инициализируются в порядке объявления, как они появляются в списке базовых спецификаторов.
    (независимо от порядка установки mem-инициализаторов).
  • Затем, Нестатические члены данных инициализируются в том порядке, в котором они были объявлены в определении класса.
    (опять же независимо от порядка mem-инициализаторов).
  • Наконец, составной оператор тела конструктора выполняется

Так, как указано в Предложение инициализаторов не статических данных (Проблема 3):

Третья проблема заключается в том, что поиск в области классов может превратить ошибку времени компиляции в ошибку времени выполнения:

struct S {
int i = j; // ill-formed without forward lookup, undefined behavior with
int j = 3;
};

(Если компилятор не поймал меня, я мог бы быть инициализирован с неопределенным значением j.)

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]