我声称这个程序应该是格式良好的:它声明了一个 constexpr 的成员函数S<int>
。然而,GCC 和 Clang 都拒绝这个程序。
template<class T>
struct S {
constexpr int foo() {
if constexpr (std::is_same_v<T, int>) {
return 0;
} else {
try {} catch (...) {}
return 1;
}
}
};
int main()
{
S<int> s;
return s.foo(); // expect "return 0"
}
海湾合作委员会 说:
错误:“constexpr”函数中的“try”
铿锵声 说:
错误:constexpr 函数中不允许的语句
他们似乎都没有注意到“try”语句位于语句的废弃分支中if constexpr
。
如果我将try
/ catch
out 分解为非 constexpr成员函数void trycatch()
,那么 Clang 和 GCC 都会再次对代码感到满意,即使它的行为应该等同于不满意的版本。
template<class T>
struct S {
void trycatch() {
try {} catch (...) {}
}
constexpr int foo() {
if constexpr (std::is_same_v<T, int>) {
return 0;
} else {
trycatch(); // This is fine.
return 1;
}
}
};
这是
- GCC 和 Clang 中的错误?
- GCC 和 Clang 忠实执行的标准中的缺陷?
- 由于“有条件的 constexprness”而导致的实施质量问题
foo()
?
(不相关的背景:我正在any::emplace<T>()
为一个分配器感知版本实现 constexpr,any
其分配器可能是 constexpr-per- P0639(即它可能缺少deallocate
成员函数)或可能不是。在前一种情况下,我们不想要或不需要try
; 在后一种情况下,如果throws的构造函数我们需要try
调用。)deallocate
T