Инициализатор «sizeof (T)» встроенного статического авто … Нужно ли создавать экземпляр?

Что должно произойти, если тип выражения не зависит, но мы используем его для инициализации статической автоматической переменной? GCC и Clang отличаются по своему поведению

template<typename T>
struct A {
static inline auto x = sizeof(T{}.f);
};

A<int> a;

GCC не вызывает ошибку. Но Clang считает, что это недопустимо, потому что он создает экземпляр операнда «sizeof». GCC, кажется, пропустить этот шаг, потому что sizeof(T{}.f) всегда имеет тип size_t (не зависит от типа), поэтому он уже знает тип x без конкретизации. Оба компилятора соответственно отклоняют программу, если мы ссылаемся на xнапример, (void) a.x;,

Это даже должно решить тип x совсем? Начиная с C ++ 14, язык позволяет хранить вещи (например, функции) с «типом заполнителя» и выполнять отложенную реализацию, чтобы узнать о фактическом типе возврата позже, если я правильно помню. Это должно применить это к x так хорошо, сохраняя x с типом заполнителя, пока мы не обратимся к a.x?

Какой компилятор верен в соответствии со стандартами?


РЕДАКТИРОВАТЬ

Кто-то спросил

хм, разве это не должно быть эквивалентно этому?

template<typename T>
struct A {
static const std::size_t x;
};

template<typename T>
inline constexpr std::size_t A<T>::x = sizeof(T{}.f);

Разница, и что касается меня в моем вопросе, состоит в том, что статический член данных в моем вопросе auto, Поэтому, чтобы узнать тип xВам нужно знать тип инициализатора. Похоже, что Clang с готовностью создает инициализатор, чтобы получить тип. Но GCC нет, по-видимому? Я хотел бы понять, что происходит.

5

Решение

От [Temp.inst] / 3:

Если элемент шаблона класса или шаблон элемента не был явно создан или явно специализирован, специализация члена создается неявно, когда на специализацию ссылаются в контексте, который требует определения элемента; особенно, инициализация (и любые связанные побочные эффекты) элемента статических данных не происходит, если только сам элемент статических данных не используется таким образом, который требует определения элемента статических данных.

Просто пишу A<int> a; не использует ни A<int>::x таким образом, чтобы его определение существовало, поэтому его инициализация не должна происходить. GCC правильно.

2

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

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

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