请考虑以下几点:
#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包装:t‘在匿名聚合中不允许构造函数 MyType t; ^ 编译失败
注意,static_assert确保MyType是一个标准布局类型,一个平凡型,而且实际上是吊舱 (请注意,在C++11之后,POD允许有构造函数)。
关于匿名结构中允许哪些类型,我找不到权威的东西。我所发现的(主要是在这里)表明,作为一个POD类型是足够的。显然,事实并非如此。
我的问题是:如果作为一个类型实际上不足以在一个匿名结构中存在,那么是什么?又或者,由于GCC不同于所有其他编译器,这是GCC的问题吗?
发布于 2016-08-22 00:58:12
就标准而言,匿名结构是C特性。任何C++标准都不允许这样做。
我找不到详细的gcc文档,关于他们的扩展,以提供C++的功能。我发现的很少是这里,但是那个页面似乎只描述了C的扩展(在C11之前,这个特性是不标准的)。
我的问题是,如果作为一个POD类型实际上不足以在一个匿名结构中,
这似乎确实是不够的。错误消息非常清楚地解释了,拥有(非平凡的)构造函数会使类不具备匿名聚合(结构)的资格。只有在C++11之前,POD才能保证这一点。
由于扩展的文档很少,而且匿名结构是C特性,所以我很想猜测,任何这样的聚合都不能使用C++特性。我相信预C++11定义的POD符合这样的要求.
快速测试似乎与我的假设相符。如果删除构造函数,则程序将使用启用的扩展进行编译。如果将struct成员命名为结构成员(将类型提升为未命名类型),则程序将成为格式良好的标准C++,并进行编译。
或者,由于GCC与所有其他编译器不同,这是否与GCC有问题?
因为这是他们实现它的方式,所以这很可能不是他们的问题。这可能是一个问题,谁希望不修改编译,一个为另一个编译器编写的非标准程序。一般来说,这是一个非标准语言特性的问题。
https://stackoverflow.com/questions/39069799
复制相似问题