[英]Can you call a constexpr function to assign a constexpr value with a forward declaration?
我发现自己处于一个奇怪的位置,错误消息“表达式未计算为常数”:
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;
}
现在我想我可以将 constexpr 值移到定义之下,但我想知道这个问题的答案。 我知道它是编译器,而不是需要 constexpr 函数的完整定义的链接器,但编译器就在下面。
我知道它是编译器,而不是需要 constexpr 函数的完整定义的链接器,但编译器在下面有它。
可以使用expr.const#5来理解程序的行为,其中指出:
5.表达式 E 是核心常量表达式,除非根据抽象机 ([intro.execution]) 的规则对 E 的求值将求值以下之一:
5.2调用未定义的 constexpr 函数;
(强调我的)
这意味着当写
//------------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();
此时的调用表达式createDynamicPipelineStateMask()
是对未定义的 constexpr 函数的调用,因此根据上面引用的语句,初始化程序不是常量表达式,这反过来意味着它不能用作初始化dynamic_state_mask
的初始化程序。 基本上,在定义函数之前,您不能在constexpr 上下文中使用调用表达式createDynamicPipelineStateMask()
。
但以下是完全没问题的。
//------------v-------------------------->note no constexpr here, this is allowed
static inline int dynamic_state_mask = createDynamicPipelineStateMask();
这一次,即使createDynamicPipelineStateMask()
没有评估为常量表达式,它仍然可以用作初始化器来初始化dynamic_state_mask
,因为我们已经从声明的左侧删除了constexpr
说明符。 基本上这不是一个constexpr 上下文,因此使用调用表达式作为初始化程序很好。
也许一个人为的例子可能会进一步说明这一点:
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.