constexpr if和static_assert [英] constexpr if and static_assert
问题描述
P0292R1 constexpr(如果已已包含,对于C ++ 17而言,该计划已步入正轨。似乎有用(并且可以替代SFINAE的用法),但是有关错误分支中的 static_assert
格式错误,无需诊断的注释我:
如果不建议在
constexpr的未使用分支中撤消static_assert声明。
void f(){
如果constexpr(false)
static_assert(false); //格式错误的
}
template< class T>
void g(){
if constexpr(false)
static_assert(false); //格式错误;否
//模板定义需要诊断
}
我认为完全禁止在constexpr中使用 static_assert
如果(至少是false /不带分支,但这实际上意味着这样做不是安全或有用的事情)。 / p>
这是如何从标准文字中得出的?我发现在提案措辞中没有提及 static_assert
,C ++ 14 constexpr函数确实允许 static_assert
(详细信息请参见cppreference: constexpr )。
是吗隐藏在这个新句子中(在6.4.1之后)? :
当constexpr if语句出现在模板实体中时,在封装模板或通用lambda的实例化过程中,
b $ ba丢弃的语句未实例化。
从那以后,我假设它也是禁止的,不需要诊断,就可以调用调用图上的某处的其他constexpr(模板)函数可能会调用 static_assert
。
底线:
如果我的理解是正确的,那不是吗对 constexpr if
的安全性和实用性设置了相当严格的限制,因为我们必须(从文档或代码检查中知道)有关任何使用 static_assert的信息
?
更新:
此代码无需警告即可编译( clang head 3.9.0),但据我了解病状,无需诊断。有效吗?
template<类型名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< class>的同一规则。无效f(){返回1; }
。 [temp.res] / 8 ,新的更改以粗体显示:
该程序格式错误,无需诊断,如果:
- 否可以为
模板中的模板或constexpr if
语句([stmt.if])的子语句
生成有效的专业化并且模板未实例化,或者
- [...]
对于包含 static_assert
且条件独立且评估为 false $的模板,无法生成有效的专业化名称c $ c>,因此程序是格式错误的NDR。
static_assert
s具有从属条件,可以至少有一种类型的计算结果为 true
。
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
}
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).
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).
Is it hiding in this new sentence (after 6.4.1) ? :
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.
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
.
Bottom line:
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?
Update:
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>();
}
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:
- 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- [...]
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
s with a dependent condition that can evaluate to true
for at least one type are not affected.
这篇关于constexpr if和static_assert的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!