如果我尝试编译以下 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++ 中,类的成员函数的内联定义仅在解析类中的每个声明后才会解析。因此,在第一个示例中,编译器在声明
number()
时看不到 function()
的定义。
(没有发布的 clang 版本支持评估 constexpr 函数,因此您的任何测试用例都无法在那里工作。)
这将编译成功:
struct Sub{constexpr Sub(int i){}};
struct Test{
static constexpr Sub s=0;
};