Рассмотрим следующий пример:
template<int N>
struct foo {
constexpr foo() : a() {}
int a[N];
};
int main() {
foo< (foo<1>{}).a[0] > f;
}
При попытке скомпилировать это clang выводит foo<0>
как тип f
while g++
вылетает с внутренней ошибкой компилятора.
Однако гарантировано ли значение- a
member of foo<1>
равным нулю, или это неопределенное / неопределенное поведение?
Значение инициализатора a()
- члена инициализируется foo::a
(через [class.base.init] / 7, это приводит к [dcl.init] / 11). [dcl.init] / 8 указывает, что инициализация значения для массивов инициализирует значение каждого элемента массива. Для int
s (и других основных типов) это приводит к нулевой инициализации.
Это не причем constexpr
. Внутренняя ошибка компилятора обычно является ошибкой; это также может означать, что вы превысили некоторые ограничения, определенные реализацией, что, похоже, здесь не так.
Как отмечает Петр С. в комментарии, выражение foo< (foo<1>{}).a[0] >
, если предположить foo<1>{}).a[0] == 0
, приводит к объявлению массива нулевого размера. Это не разрешено в C ++; так что можно утверждать, что поведение g ++ соответствует требованиям.
Эта статья взята из Интернета, укажите источник при перепечатке.
Если есть какие-либо нарушения, пожалуйста, свяжитесь с[email protected] Удалить.
я говорю два предложения