[英]Can you call a constexpr function to assign a constexpr value with a forward declaration?
I found myself in a weird spot, with the error message "expression did not evaluate to a constant":我发现自己处于一个奇怪的位置,错误消息“表达式未计算为常数”:
constexpr uint64 createDynamicPipelineStateMask();
static inline constexpr uint64 dynamic_state_mask = createDynamicPipelineStateMask();
struct CullMode
{
static constexpr inline bool bIsDynamicState = false;
static constexpr inline uint64 mask = 0;
};
constexpr uint64 createDynamicPipelineStateMask()
{
uint64 dynamic_mask = 0;
if constexpr (CullMode::bIsDynamicState) dynamic_mask |= CullMode::mask;
return dynamic_mask;
}
Now I guess I could just move the constexpr value to below the definition, but I wanted to know the answer to this question.现在我想我可以将 constexpr 值移到定义之下,但我想知道这个问题的答案。 I know that it's compiler, and not the linker that needs the full definition of the constexpr function, but the compiler has it right below.
我知道它是编译器,而不是需要 constexpr 函数的完整定义的链接器,但编译器就在下面。
I know that it's compiler, and not the linker that needs the full definition of the constexpr function, but the compiler has it right below .
我知道它是编译器,而不是需要 constexpr 函数的完整定义的链接器,但编译器在下面有它。
The behavior of the program can be understood using expr.const#5 which states:可以使用expr.const#5来理解程序的行为,其中指出:
5. An expression E is a core constant expression unless the evaluation of E, following the rules of the abstract machine ([intro.execution]), would evaluate one of the following:
5.表达式 E 是核心常量表达式,除非根据抽象机 ([intro.execution]) 的规则对 E 的求值将求值以下之一:
5.2 an invocation of an undefined constexpr function ;
5.2调用未定义的 constexpr 函数;
(emphasis mine) (强调我的)
This means that when writing这意味着当写
//------------vvvvvvvvv--------------------------> note the constexpr here, this is not allowed because the call expression cannot be used in a constexpr context until the function is defined
static inline constexpr int dynamic_state_mask = createDynamicPipelineStateMask();
the call expression createDynamicPipelineStateMask()
at this point is an invocation of an undefined constexpr function and so the initializer is not a constant expression according to the above quoted statement which in turn means that it cannot be used as an initializer to initialize dynamic_state_mask
.此时的调用表达式
createDynamicPipelineStateMask()
是对未定义的 constexpr 函数的调用,因此根据上面引用的语句,初始化程序不是常量表达式,这反过来意味着它不能用作初始化dynamic_state_mask
的初始化程序。 Basically, you can't use the call expression createDynamicPipelineStateMask()
in a constexpr context until the function is defined.基本上,在定义函数之前,您不能在constexpr 上下文中使用调用表达式
createDynamicPipelineStateMask()
。
But the following is perfectly fine.但以下是完全没问题的。
//------------v-------------------------->note no constexpr here, this is allowed
static inline int dynamic_state_mask = createDynamicPipelineStateMask();
This time, even though createDynamicPipelineStateMask()
does not evaulate to a constant expression, it can still be used as an initializer to initialize dynamic_state_mask
as we have removed the constexpr
specifier from the left hand side of the declaration.这一次,即使
createDynamicPipelineStateMask()
没有评估为常量表达式,它仍然可以用作初始化器来初始化dynamic_state_mask
,因为我们已经从声明的左侧删除了constexpr
说明符。 Basically this isn't a constexpr context and so using the call expression as an initializer is fine.基本上这不是一个constexpr 上下文,因此使用调用表达式作为初始化程序很好。
Perhaps a contrived example might clear this further:也许一个人为的例子可能会进一步说明这一点:
constexpr int func();
//constexpr int i = func(); //not allowed as the call expression func() at this point is an invocation of an undefined constexpr function and so the initializer is not a constant expression
int i = func(); //allowed
constexpr int func()
{
return 4;
}
constexpr int j = func(); //allowed
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.