在以下 C++20 函数模板中:
template<int i>
void f() {
if constexpr (i == 1)
g();
else if constexpr (i == 2)
h();
else
??? // <--error
}
有什么我们可以写的东西在编译时???
调用会失败吗?f<3>()
在以下 C++20 函数模板中:
template<int i>
void f() {
if constexpr (i == 1)
g();
else if constexpr (i == 2)
h();
else
??? // <--error
}
有什么我们可以写的东西在编译时???
调用会失败吗?f<3>()
问题是constexpr if被丢弃的语句对于每个可能的专业化都不是格式错误的。[temp.res.general]/6
(强调我的)
可以在任何实例化之前检查模板的有效性。
该程序格式错误,不需要诊断,如果:
- 无法为模板或constexpr if语句的子语句生成有效的特化模板内的语句并且模板未实例化,或
您可以使用始终为 的类型相关表达式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");
}
标准的习惯用法是有一个依赖模板,专门用于std::false_type
,如下所示:
template<int T> 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, "i can only be 1 or 2");
}
你不能只说的原因
static_assert(false, "i can only be 1 or 2");
是语言中的一条规则,它表示对于封闭模板的每个if constexpr
可能的实例化,an 的分支不能为假。
添加可以专门用于std::true_type
解决此限制的模板。
写吧
template<int i>
void f() {
if constexpr (i == 1)
g();
else {
static_assert(i == 2);
h();
}
}
只需要重写最后一个条件。
由于其他答案中给出的原因,我将按以下方式重写:
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();
}
这样,就可以避免类模板。