C++ 如何在constexpr if else链中导致静态错误?
在以下C++20函数模板中:C++ 如何在constexpr if else链中导致静态错误?,c++,constexpr,c++20,static-assert,if-constexpr,C++,Constexpr,C++20,Static Assert,If Constexpr,在以下C++20函数模板中: template<int i> void f() { if constexpr (i == 1) g(); else if constexpr (i == 2) h(); else ??? // <--error } 模板 void f(){ 如果constexpr(i==1) g(); 如果constexpr(i==2),则为else h(); 其他的 问题是,对于每一种可能的专
template<int i>
void f() {
if constexpr (i == 1)
g();
else if constexpr (i == 2)
h();
else
??? // <--error
}
模板
void f(){
如果constexpr(i==1)
g();
如果constexpr(i==2),则为else
h();
其他的
问题是,对于每一种可能的专门化,被丢弃的声明都不可能是格式错误的
(强调矿山)
可以在任何实例化之前检查模板的有效性
如果出现以下情况,程序格式不正确,无需诊断:
- 无法为模板或a生成有效的专门化
模板中语句的子语句,以及
模板未实例化,或
您可以使用始终为false
的类型相关表达式
template<int i> struct dependent_false : std::false_type {};
template<int i>
void f() {
if constexpr (i == 1)
g();
else if constexpr (i == 2)
h();
else
static_assert(dependent_false<i>::value, "Must be 1 or 2");
}
template-struct-dependent\u-false:std::false\u-type{};
模板
void f(){
如果constexpr(i==1)
g();
如果constexpr(i==2),则为else
h();
其他的
静态_断言(dependent_false::value,“必须是1或2”);
}
这方面的标准习惯用法是有一个依赖模板,专门用于std::false\u type
,如下所示:
template<int T> struct dependent_false : std::false_type {};
是语言中的一条规则,该规则规定,如果constexpr
对封闭模板的每个可能实例化都不能为false,则的分支
添加一个可以专门用于std::true_type
的模板可以绕过此限制。基于其他答案中给出的原因,我将以以下方式重写:
template<int i>
void f() {
static_assert(i == 1 || i == 2, "must be 1 or 2");
if constexpr (i == 1)
g();
if constexpr (i == 2)
h();
}
模板
void f(){
静态_断言(i==1 | | i==2,“必须是1或2”);
如果constexpr(i==1)
g();
如果constexpr(i==2)
h();
}
这样,就可以避免使用类模板。只需编写
template<int i>
void f() {
if constexpr (i == 1)
g();
else {
static_assert(i == 2);
h();
}
}
模板
void f(){
如果constexpr(i==1)
g();
否则{
静态断言(i==2);
h();
}
}
这只需要重写最后一个条件。这是一个值得考虑的想法,但在现实世界的代码中,if-else链中有更多的分支,条件表达式也更复杂,因此建议您的解决方案有一个干冲突,即所有条件都必须重复两次(一次在静态断言中,一次在条件中)AndrewTomazos在这种违反性的行为之前变得令人担忧,我会考虑“一个代码> f <代码>对于不同的值<不同的代码> > <代码>是正确的模式。每个if if链是一组对互不相容的条件做不同的事情的声明。)作为C++ 20,<代码>模板无效F.()要求(i==1){g();}模板void f()需要(i==2){h();}
:-)但我可能会选择标记分派void f(std::integral_constant){g();}模板void f(){f(std::integral_constant{})}
@Jarod42:现在重复函数模板声明模板rf(params)时有一个完全违反
N次,而不是一次。;)
template<int i>
void f() {
static_assert(i == 1 || i == 2, "must be 1 or 2");
if constexpr (i == 1)
g();
if constexpr (i == 2)
h();
}
template<int i>
void f() {
if constexpr (i == 1)
g();
else {
static_assert(i == 2);
h();
}
}