Bob*_*tti 15 gcc clang language-lawyer c++11 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();
}
Run Code Online (Sandbox Code Playgroud)
命令行调用:
$ 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();
Run Code Online (Sandbox Code Playgroud)
如果我改为bar不再是模板,就像在
class bar
{
public:
struct foo
{
int array[10];
};
int baz()
{
return sizeof(foo::array);
}
};
int main(void)
{
bar b;
return b.baz();
}
Run Code Online (Sandbox Code Playgroud)
然后代码干净利落地编译.值得注意的是,GCC 5.2.1接受两个版本std=c++11.另外值得注意的是,移入array封闭的类模板体(但将其作为模板)也会导致clang接受此操作.
相对于标准,哪种行为是正确的?这是GCC,clang或两者中的错误吗?
(我问过关于cfe用户的同样问题,但到目前为止还没有得到回复).
这肯定是一个铿锵的错误; 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(); }
Run Code Online (Sandbox Code Playgroud)
当在模板实例方法中的未评估上下文中访问依赖类型成员时,该错误就会展示.Clang实施的n2253规则允许在未评估的上下文(以及后来的改进)中使用非静态数据成员,这看起来相当脆弱,并且与模板交互不良; 一个类似(虽然不同)的错误是http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20151019/141535.html.
我找不到任何迹象表明已经向Clang Bugzilla报告过; 你可能想要开一个新的bug.
根据您的具体情况,变通方法可能包括在实例方法之外移动静态类型和值计算; 特别是即使baz是static成员函数也足以说服clang接受你的代码.
| 归档时间: |
|
| 查看次数: |
340 次 |
| 最近记录: |