Правила для анонимных агрегатов

Учтите следующее:

#include <type_traits>

struct MyType {
int val;
MyType(void) = default;
MyType(int v) : val(v) {}
};
static_assert(std::is_standard_layout<MyType>::value,"Implementation error!");
static_assert(std::is_trivial<MyType>::value,"Implementation error!");
static_assert(std::is_pod<MyType>::value,"Implementation error!");

struct Wrapper {
struct {
MyType t;
};
};

MSVC, Clang и Intel C ++ все прекрасно скомпилируют. Но g++4.9 foo.cpp -std=c++11 говорит мне:

14: ошибка: член ‘MyType Wrapper ::<анонимная структура> :: t ‘с конструктором, не допускаемым в анонимном агрегате
MyType t;
^
Компиляция не удалась

Обратите внимание, что static_assertубедитесь, что MyType это стандартное расположение наберите «А тривиальный тип, и к тому же на самом деле POD (обратите внимание, что после C ++ 11 POD разрешено иметь конструкторы).


Я не смог найти ничего авторитетного в том, какие типы разрешены внутри анонимных структур. То, что я нашел (в основном здесь, на SO), говорит о том, что достаточно быть POD-типом. Видимо, это не так.

Мой вопрос: Если для того, чтобы быть в анонимной структуре, на самом деле недостаточно POD-типа, что является достаточно? Или, возможно, поскольку GCC отличается от всех других компиляторов, это проблема с GCC?

5

Решение

Что касается стандартов, анонимные структуры являются функцией C. Они не разрешены никаким стандартом C ++.

Я не мог найти подробную документацию GCC об их расширении, чтобы обеспечить функцию в C ++. Что мало я нашел Вот, но эта страница, кажется, описывает только расширение для C (до C11 эта функция не была стандартной).

Мой вопрос: если для того, чтобы быть в анонимной структуре, на самом деле недостаточно POD-типа,

Это действительно кажется недостаточным. Сообщение об ошибке довольно ясно объясняет, что наличие (нетривиального) конструктора лишает класс возможности быть анонимным агрегатом (структурой). POD будет гарантировать это только до C ++ 11.

Поскольку, как представляется, документации для расширения недостаточно, а анонимные структуры являются функцией C, я склонен предположить, что любой такой агрегат не должен использовать функции C ++. Я считаю, что определение POD до C ++ 11 удовлетворяет такому требованию.

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

Или, возможно, поскольку GCC отличается от всех других компиляторов, это проблема с GCC?

Так как они это реализовали, вполне возможно, что с ними проблем нет. Это может быть проблемой для тех, кто хочет скомпилировать без изменений нестандартную программу, написанную для другого компилятора. Это проблема с нестандартными языковыми функциями в целом.

5

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

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