Учтите следующее:
#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?
Что касается стандартов, анонимные структуры являются функцией C. Они не разрешены никаким стандартом C ++.
Я не мог найти подробную документацию GCC об их расширении, чтобы обеспечить функцию в C ++. Что мало я нашел Вот, но эта страница, кажется, описывает только расширение для C (до C11 эта функция не была стандартной).
Мой вопрос: если для того, чтобы быть в анонимной структуре, на самом деле недостаточно POD-типа,
Это действительно кажется недостаточным. Сообщение об ошибке довольно ясно объясняет, что наличие (нетривиального) конструктора лишает класс возможности быть анонимным агрегатом (структурой). POD будет гарантировать это только до C ++ 11.
Поскольку, как представляется, документации для расширения недостаточно, а анонимные структуры являются функцией C, я склонен предположить, что любой такой агрегат не должен использовать функции C ++. Я считаю, что определение POD до C ++ 11 удовлетворяет такому требованию.
Быстрый тест, кажется, согласен с моей гипотезой. Если вы удалите конструктор, программа компилируется с включенным расширением. Если вы называете член структуры (продвигая тип, чтобы быть неназванный), программа становится хорошо сформированным стандартом C ++, а также компилируется.
Или, возможно, поскольку GCC отличается от всех других компиляторов, это проблема с GCC?
Так как они это реализовали, вполне возможно, что с ними проблем нет. Это может быть проблемой для тех, кто хочет скомпилировать без изменений нестандартную программу, написанную для другого компилятора. Это проблема с нестандартными языковыми функциями в целом.
Других решений пока нет …