6

如果我尝试编译以下 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标准的哪些条款说错了?

4

2 回答 2

5

在 C++ 中,类的成员函数的内联定义仅在类中的每个声明被解析后才被解析。因此,在您的第一个示例中,编译器看不到声明number()点的定义function()

(没有已发布的 clang 版本支持评估 constexpr 函数,因此您的任何测试用例都不会在那里工作。)

于 2011-11-12T23:38:06.920 回答
1

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

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

“错误:'constexpr Test::Sub::Sub(int)' 在常量表达式中调用”在 gcc 4.7.1 上。而这将成功编译:

struct Sub{constexpr Sub(int i){}};
struct Test{
    static constexpr Sub s=0;
};
于 2012-12-08T06:32:14.373 回答