在同一个类中使用constexpr作为模板形参出错

Error using a constexpr as a template parameter within the same class

本文关键字:形参 出错 constexpr 同一个      更新时间:2023-10-16

如果我尝试编译以下c++ 0x代码,我会得到一个错误:

template<int n> struct foo { };
struct bar {
    static constexpr int number() { return 256; }
    void function(foo<number()> &);
};

对于gcc 4.6.1,错误信息是:

test.cc:6:27: error: ‘static constexpr int bar::number()’ used before its definition
test.cc:6:28: note: in template argument for type ‘int’

对于clang 2.8,错误消息是:

test.cc:6:20: error: non-type template argument of type 'int' is not an integral
      constant expression
        void function(foo<number()> &);
                          ^~~~~~~~
1 error generated.

如果我将constexpr函数移动到基类,它在gcc上工作,并在clang上给出相同的错误信息:

template<int n> struct foo { };
struct base {
    static constexpr int number() { return 256; }
};
struct bar : base {
    void function(foo<number()> &);
};

是代码错误,还是gcc 4.6对c++ 0x的实现的限制或错误?如果代码是错误的,为什么是错误的,c++ 11标准的哪些子句说它是错误的?

在c++中,类的成员函数的内联定义只有在类中的每个声明被解析之后才会被解析。因此,在第一个示例中,编译器无法在声明function()的地方看到number()的定义。

(没有clang的发布版本支持constexpr函数的求值,所以你的测试用例都不能在那里工作。)

我有一个类似的错误与以下代码:

struct Test{
     struct Sub{constexpr Sub(int i){}};
    static constexpr Sub s=0;
};

在gcc 4.7.1中"error: 'constexpr Test::Sub::Sub(int)'在常量表达式中被调用"而这将成功编译:

struct Sub{constexpr Sub(int i){}};
struct Test{
    static constexpr Sub s=0;
};