获取嵌套在 class 模板中的结构的 `sizeof` 非静态成员是否非法?
Is it illegal get `sizeof` non-static member of struct nested within class template?
在clang/llvm 3.6.2中,以下代码在用std=c++11
编译时会导致编译错误:
template <typename T=void>
class bar
{
public:
struct foo
{
int array[10];
};
int baz()
{
return sizeof(foo::array);
}
};
int main(void)
{
bar<> b;
return b.baz();
}
命令行调用:
$ clang++ -std=c++11 nonstatic.cpp -o nonstatic
nonstatic.cpp:12:28: error: invalid use of non-static data member 'array'
return sizeof(foo::array);
~~~~~^~~~~
nonstatic.cpp:20:14: note: in instantiation of member function
'bar<void>::baz' requested here
return b.baz();
如果我将 bar
更改为不再是模板,如
class bar
{
public:
struct foo
{
int array[10];
};
int baz()
{
return sizeof(foo::array);
}
};
int main(void)
{
bar b;
return b.baz();
}
然后代码编译干净。值得注意的是,GCC 5.2.1 接受 std=c++11
下的两个版本。同样值得注意的是,将 array
移动到封闭的 class 模板主体中(但将其保留为模板)也会导致 clang 接受这个。
相对于标准,哪种行为是正确的?这是 GCC、clang 或两者中的错误吗?
(我在 cfe-users 上询问了同样的 question,但到目前为止还没有收到任何回复)。
这肯定是一个 clang 错误; sizeof
表达式的操作数是一个 id-expression 表示一个非静态数据成员,所以 [expr.prim.general]/13 成立。这是一个简化的例子:
template<class T> struct M { int f() { return sizeof(T::x); } };
struct S { int x; };
int main() { return M<S>{}.f(); }
当在模板实例方法内的未计算上下文中访问依赖类型成员时,会出现该错误。 Clang 对 n2253 rule enabling the use of non-static data members in unevaluated context (and later improvements) appears rather fragile and to interact badly with templates; a similar (though distinct) bug is http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20151019/141535.html.
的实现
我找不到任何迹象表明这已经报告给 Clang Bugzilla;你可能想打开一个新的错误。
根据您的情况,解决方法可能包括将静态类型和值计算移到实例方法之外;值得注意的是,即使将 baz
设为 static
成员函数也足以说服 clang 接受您的代码。
在clang/llvm 3.6.2中,以下代码在用std=c++11
编译时会导致编译错误:
template <typename T=void>
class bar
{
public:
struct foo
{
int array[10];
};
int baz()
{
return sizeof(foo::array);
}
};
int main(void)
{
bar<> b;
return b.baz();
}
命令行调用:
$ clang++ -std=c++11 nonstatic.cpp -o nonstatic
nonstatic.cpp:12:28: error: invalid use of non-static data member 'array'
return sizeof(foo::array);
~~~~~^~~~~
nonstatic.cpp:20:14: note: in instantiation of member function
'bar<void>::baz' requested here
return b.baz();
如果我将 bar
更改为不再是模板,如
class bar
{
public:
struct foo
{
int array[10];
};
int baz()
{
return sizeof(foo::array);
}
};
int main(void)
{
bar b;
return b.baz();
}
然后代码编译干净。值得注意的是,GCC 5.2.1 接受 std=c++11
下的两个版本。同样值得注意的是,将 array
移动到封闭的 class 模板主体中(但将其保留为模板)也会导致 clang 接受这个。
相对于标准,哪种行为是正确的?这是 GCC、clang 或两者中的错误吗?
(我在 cfe-users 上询问了同样的 question,但到目前为止还没有收到任何回复)。
这肯定是一个 clang 错误; sizeof
表达式的操作数是一个 id-expression 表示一个非静态数据成员,所以 [expr.prim.general]/13 成立。这是一个简化的例子:
template<class T> struct M { int f() { return sizeof(T::x); } };
struct S { int x; };
int main() { return M<S>{}.f(); }
当在模板实例方法内的未计算上下文中访问依赖类型成员时,会出现该错误。 Clang 对 n2253 rule enabling the use of non-static data members in unevaluated context (and later improvements) appears rather fragile and to interact badly with templates; a similar (though distinct) bug is http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20151019/141535.html.
的实现我找不到任何迹象表明这已经报告给 Clang Bugzilla;你可能想打开一个新的错误。
根据您的情况,解决方法可能包括将静态类型和值计算移到实例方法之外;值得注意的是,即使将 baz
设为 static
成员函数也足以说服 clang 接受您的代码。