问题描述
我遇到了一个违反直觉的错误,即无法将 constexpr
函数的值赋给 constexpr
literal(希望我使用的语言是正确的)。下面是例子:
class MyClass {
public:
static constexpr int FooValue(int n){返回n + 5; }
static constexpr int Foo5 = FooValue(5); //编译错误
static constexpr int Foo5Alt(void){return FooValue(5); } // OK
};
在GCC 4.8.4中,
Foo5
是标记为字段初始值设定项不是常量
。找到暗示GCC的旧版本可能是罪魁祸首。所以我将它插入(GCC 6.2.0),并得到'static constexpr int MyClass :: FooValue(int)'在定义完成之前在常量表达式中调用
。我添加了 Foo5Alt()
,它将它的值作为 constexpr
函数返回,而不是文字,并且编译得很好。
我想我不是为什么 FooValue(5)
不能用作<$ c的初始值设定项$ C> Foo5
。 FooValue(int n)
的定义是完整的,不是吗? {return n + 5; }
是整个定义。 constexpr
表示可以在编译时完全评估的表达式,为什么不能用它来定义 constexpr
literal?
我错过了多少C ++?
解决方案在C ++中,类的成员函数的内联定义仅在类的声明完成后才被解析。因此即使编译器知道了 MyClass :: FooValue(int)
,它也没有看到它的定义,因此它不能在 constexpr
表达式中使用。
一般的解决方法是坚持 constexpr
成员函数,或者在类之外声明 constexpr
常量。
I've run into what seems a counterintuitive error, namely, the inability to assign the value of a constexpr
function to a constexpr
literal (hope I'm using the language right). Here's the example:
class MyClass {
public:
static constexpr int FooValue(int n) { return n + 5; }
static constexpr int Foo5 = FooValue(5); // compiler error
static constexpr int Foo5Alt(void) { return FooValue(5); } // OK
};
In GCC 4.8.4, Foo5
is flagged for field initializer is not constant
. Found this thread suggesting that the older version of GCC might be the culprit. So I plugged it into Coliru (GCC 6.2.0) and got the error 'static constexpr int MyClass::FooValue(int)' called in a constant expression before its definition is complete
. I added Foo5Alt()
which returns its value as a constexpr
function rather than literal, and that compiles fine.
I guess I'm not following why FooValue(5)
can't be used as the initializer for Foo5
. The definition for FooValue(int n)
is complete, isn't it? { return n + 5; }
is the entire definition. constexpr
denotes an expression that can be fully evaluated at compile time, so why can it not be used to define the return value of a constexpr
literal?
What subtlety of C++ am I missing?
解决方案 In C++, inline definitions of member functions for a class are only parsed after the declaration of the class is complete.
So even though the compiler "knows" about MyClass::FooValue(int)
, it hasn't "seen" its definition yet, and hence it can't be used in a constexpr
expression.
A general workaround for this is to stick to constexpr
member functions, or declare constexpr
constants outside the class.
这篇关于C ++ 11 - 无法使用constexpr函数定义constexpr文字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!