【问题标题】:decltype fails on struct member declared in template classdecltype 在模板类中声明的结构成员上失败
【发布时间】:2018-07-31 08:35:18
【问题描述】:

我遇到代码无法为我正在使用的外部库编译的问题。我相信这个库用 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());

我的问题如下:

  • 预期的行为是什么?

  • 在 c++11 中添加了非静态成员上的 decltype。这是否适用于模板类中声明的那些?

  • 这是编译器错误吗?还是使用 gcc 的不合格代码示例?

【问题讨论】:

  • @ArnavBorborah 这是常见的误解,事实并非如此。仅保留带有前导下划线后跟小写字母的全局范围名称。
  • @SergeyA 啊,you're right!我猜你每天都会学到一些新东西! (但我还是不会用这样的名字)
  • @Arnav Borborah 它们仅在后跟第二个下划线(所有包含双下划线 anywhere 的名称都被保留)或大写字母时才被保留。但是,我同意,一般来说,避免使用带有下划线的名称是一个好主意(很容易出错)。 _Foo__foofoo__bar 一样被保留,但 _foo 不是。
  • @JesperJuhl 太多人习惯于用_ 来命名私有成员变量。很高兴知道它是允许的:D
  • 我因在课堂上使用 _variableName 而被嘲笑...我知道它是为全局范围保留的,但不是作为课堂成员!

标签: c++ c++11 templates gcc clang++


【解决方案1】:

这是旧版本 Clang 中的一个错误,并在 Clang 3.9.0 中修复: https://godbolt.org/g/zqFxL2

规范性标准:

8.2.3:在某些情况下,会出现未计算的操作数 ([expr.prim.req], [expr.typeid], [expr.sizeof], [expr.unary.noexcept], [dcl.type.simple],[temp])。未计算的操作数不会被计算。 [ 注意:在未计算的操作数中,非静态类成员可能是 命名 ([expr.prim]) 和命名对象或函数不,通过 本身,要求提供定义([basic.def.odr])。一个 未计算的操作数被视为完整表达式。 — 尾注 ]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 2021-11-14
    • 2020-09-02
    • 1970-01-01
    • 2014-10-04
    • 2011-01-30
    • 1970-01-01
    相关资源
    最近更新 更多