C++ 如何在constexpr if else链中导致静态错误?

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(); 其他的 问题是,对于每一种可能的专

在以下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();
其他的

问题是,对于每一种可能的专门化,被丢弃的声明都不可能是格式错误的

(强调矿山)

可以在任何实例化之前检查模板的有效性

如果出现以下情况,程序格式不正确,无需诊断:

  • 无法为模板或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();
    }
}