decltype 在模板 class 中声明的结构成员上失败
decltype fails on struct member declared in template class
我遇到代码无法为我正在使用的外部库编译的问题。我相信这个库可以用 gcc 编译得很好,但是它不能用 clang 为我编译。
我可以按如下方式重新创建问题
template <class T>
class A {
public:
struct B {
int a;
};
void test();
private:
T _t;
};
template <class T>
void A<T>::test()
{
printf("Result %d", std::numeric_limits<decltype(B::a)>::max());
}
int main(int argc, char** argv)
{
auto t = A<int>();
t.test();
return 0;
}
在 clang 上编译失败,出现以下错误
error: invalid use of non-static data member 'a' printf("Result %d", std::numeric_limits<decltype(B::a)>::max());
我的问题如下:
预期的行为是什么?
非静态成员的 decltype 是在 c++11 中添加的。这是否适用于模板 类 中声明的内容?
这是编译器错误吗?或者使用 gcc 的不一致代码示例?
这是老版本Clang的bug,Clang 3.9.0修复了:
https://godbolt.org/g/zqFxL2
规范标准:
8.2.3: In some contexts, unevaluated operands appear ([expr.prim.req],
[expr.typeid], [expr.sizeof], [expr.unary.noexcept],
[dcl.type.simple], [temp]). An unevaluated operand is not evaluated.
[ Note: In an unevaluated operand, a non-static class member may be
named ([expr.prim]) and naming of objects or functions does not, by
itself, require that a definition be provided ([basic.def.odr]). An
unevaluated operand is considered a full-expression. — end note ]
我遇到代码无法为我正在使用的外部库编译的问题。我相信这个库可以用 gcc 编译得很好,但是它不能用 clang 为我编译。
我可以按如下方式重新创建问题
template <class T>
class A {
public:
struct B {
int a;
};
void test();
private:
T _t;
};
template <class T>
void A<T>::test()
{
printf("Result %d", std::numeric_limits<decltype(B::a)>::max());
}
int main(int argc, char** argv)
{
auto t = A<int>();
t.test();
return 0;
}
在 clang 上编译失败,出现以下错误
error: invalid use of non-static data member 'a' printf("Result %d", std::numeric_limits<decltype(B::a)>::max());
我的问题如下:
预期的行为是什么?
非静态成员的 decltype 是在 c++11 中添加的。这是否适用于模板 类 中声明的内容?
这是编译器错误吗?或者使用 gcc 的不一致代码示例?
这是老版本Clang的bug,Clang 3.9.0修复了: https://godbolt.org/g/zqFxL2
规范标准:
8.2.3: In some contexts, unevaluated operands appear ([expr.prim.req], [expr.typeid], [expr.sizeof], [expr.unary.noexcept], [dcl.type.simple], [temp]). An unevaluated operand is not evaluated. [ Note: In an unevaluated operand, a non-static class member may be named ([expr.prim]) and naming of objects or functions does not, by itself, require that a definition be provided ([basic.def.odr]). An unevaluated operand is considered a full-expression. — end note ]