C++ C++;基于其他'的联合元素大小;s元素大小

C++ C++;基于其他'的联合元素大小;s元素大小,c++,c++11,C++,C++11,考虑以下代码: struct S { union { int arr1[10]; char arr2[sizeof(arr1)]; }; }; 它在c++03和c++11模式下使用GCC4.9.2成功编译。但是,当我将S更改为这样的模板时: template <size_t N> struct S { union { int arr1[N]; char arr2[sizeo

考虑以下代码:

struct S
{
    union
    {
        int arr1[10];
        char arr2[sizeof(arr1)];
    };
};
它在c++03和c++11模式下使用GCC4.9.2成功编译。但是,当我将
S
更改为这样的模板时:

template <size_t N>
struct S
{
    union
    {   
        int arr1[N];
        char arr2[sizeof(arr1)];
    };  
};
模板
结构
{
联盟
{   
int-arr1[N];
char arr2[sizeof(arr1)];
};  
};
我得到以下错误输出:

错误:int S:::arr1[10]”不可访问

intarr1[N]

错误:在此上下文中

chararr2[sizeof(arr1)]

Clang仅在c++11模式下编译这两个版本。我很好奇这里的正确行为是什么。也许我应该明确说明
arr2
大小是
sizeof(int)*N

您可以这样做:

template <size_t N>
class S
{
private:
    union
    {
        int arr1[N];
        char arr2[N*sizeof(int)];
    };
};
模板
S类
{
私人:
联盟
{
int-arr1[N];
字符arr2[N*sizeof(int)];
};
};

您的工会是匿名的。因此,编译器将在类级别创建
arr1
arr2

因此,
chararr2[sizeof(arr1)]不会正确引用
arr1

以下是一个解决方法:

template <size_t N>
struct S
{
    union A
    {   
        int arr1[N];
        char arr2[sizeof(arr1)];
    };  
};
模板
结构
{
联盟A
{   
int-arr1[N];
char arr2[sizeof(arr1)];
};  
};
在这里编译的很好:

通过命名联合,我们防止编译器直接包含它。然后它能够正确地检索
arr1

但这也意味着
arr1
arr2
不再是
S
的成员


<> > > <>代码>成员可以定义为其他成员< /C> >,但后者必须由编译器“查找”。< /强> >/P> 1为狡猾C++question@djechlin我偶然发现:)你提出的解决方案似乎解决了这个问题,但不知道为什么。代码编译。。。你能发布完整的代码吗?@amchacon你的编译器是什么?我有GCC4.9.2和模板版本不编译。您必须实例化模板才能触发错误
被g++接受(注意最后的
u
作为union对象的名称),因此g++对命名或未命名的union没有问题,只对匿名union有问题。有多种可能的解决方案。但是问题是某些数据成员是否可以用其他成员定义。@piotrekg2这正是我试图指出的:
成员可以用其他成员定义
,但后者必须是编译器“可查找的”。@Ninetaindo:同意,这是一个更强的假设。那么非模板匿名联合版本呢?这也在C++11之外吗?编译器在编译它时是否比严格必要的更宽容?我使用char arr2[N*sizeof(decltype(arr1[0]))做了一个测试;因为如果arr1改变了类型,而工会是匿名的,它就不起作用了:(我想你应该知道。