問題描述
P0292R1 constexpr if 已經包括,C++17 正軌.它看起來很有用(并且可以替代 SFINAE 的使用),但是關于 static_assert
在錯誤分支中格式錯誤,不需要診斷 的評論讓我感到害怕:
P0292R1 constexpr if has been included, on track for C++17. It seems useful (and can replace use of SFINAE), but a comment regarding static_assert
being ill-formed, no diagnostic required in the false branch scares me:
Disarming static_assert declarations in the non-taken branch of a
constexpr if is not proposed.
void f() {
if constexpr (false)
static_assert(false); // ill-formed
}
template<class T>
void g() {
if constexpr (false)
static_assert(false); // ill-formed; no
// diagnostic required for template definition
}
我認為在 constexpr if 中使用 static_assert
是完全禁止的(至少是 false/non-taken 分支,但這實際上意味著它不是一個安全或有用的事情).
I take it that it's completely forbidden to use static_assert
inside constexpr if (at least the false / non-taken branch, but that in practice means it's not a safe or useful thing to do).
這是如何從標準文本中得出的?我發現提案措辭中沒有提到 static_assert
,并且 C++14 constexpr 函數確實允許 static_assert
(cppreference 中的詳細信息:constexpr).
How does this come about from the standard text? I find no mentioning of static_assert
in the proposal wording, and C++14 constexpr functions do allow static_assert
(details at cppreference: constexpr).
是不是藏在這個新句子里(6.4.1之后)?:
Is it hiding in this new sentence (after 6.4.1) ? :
當 constexpr if 語句出現在模板化實體中時,在封閉模板或通用 lambda 的實例化期間,丟棄的語句不會被實例化.
When a constexpr if statement appears in a templated entity, during an instantiation of the enclosing template or generic lambda, a discarded statement is not instantiated.
從那時起,我假設也禁止調用其他 constexpr(模板)函數,這些函數在調用圖的某處可能會調用 static_assert
.
From there on, I assume that it is also forbidden, no diagnostic required, to call other constexpr (template) functions which somewhere down the call graph may call static_assert
.
底線:
如果我的理解是正確的,這是否對 constexpr if
的安全性和實用性施加了相當嚴格的限制,因為我們必須(從文檔或代碼檢查中)了解任何使用static_assert
?我的擔心是不是放錯地方了?
If my understanding is correct, doesn't that put a quite hard limit on the safety and usefulness of constexpr if
as we would have to know (from documentation or code inspection) about any use of static_assert
? Are my worries misplaced?
更新:
此代碼編譯時沒有警告(clang head 3.9.0)但據我所知格式錯誤,不需要診斷.有效與否?
This code compiles without warning (clang head 3.9.0) but is to my understanding ill-formed, no diagnostic required. Valid or not?
template< typename T>
constexpr void other_library_foo(){
static_assert(std::is_same<T,int>::value);
}
template<class T>
void g() {
if constexpr (false)
other_library_foo<T>();
}
int main(){
g<float>();
g<int>();
}
推薦答案
這是關于模板的一個完善的規則——同樣的規則允許編譯器診斷template
.[temp.res]/8 新更改加粗:
This is talking about a well-established rule for templates - the same rule that allows compilers to diagnose template<class> void f() { return 1; }
. [temp.res]/8 with the new change bolded:
程序格式錯誤,無需診斷,如果:
The program is ill-formed, no diagnostic required, if:
- 不能為模板或子語句生成有效的特化
constexpr if
語句 ([stmt.if]) 中的模板并且模板沒有被實例化,或者 - [...]
- no valid specialization can be generated for a template or a substatement
of a
constexpr if
statement ([stmt.if]) within a template and the template is not instantiated, or - [...]
不能為包含 static_assert
的模板生成有效的特化,其條件是非依賴的并且計算結果為 false
,因此該程序是格式錯誤的 NDR.
No valid specialization can be generated for a template containing static_assert
whose condition is nondependent and evaluates to false
, so the program is ill-formed NDR.
static_assert
的依賴條件可以評估為至少一種類型的 true
不受影響.
static_assert
s with a dependent condition that can evaluate to true
for at least one type are not affected.
這篇關于constexpr if 和 static_assert的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!