簡體   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