繁体   English   中英

你可以调用一个 constexpr 函数来分配一个带有前向声明的 constexpr 值吗?

[英]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

演示 Clang&Gcc ,

MSVC 演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM