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