如何解决如何在 constexpr if-else 链中导致静态错误?
在以下 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
(强调我的)
可以在任何实例化之前检查模板的有效性。
程序格式错误,无需诊断,如果:
- 无法为模板或 a 生成有效的专业化 模板中 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
的分支不能为假。
添加一个可以专门用于 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();
}
这样可以避免类模板。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。