noexcept 运算符和 enable_if_t:它们一起工作吗?
noexcept operator and enable_if_t: do they work together?
考虑以下 class:
struct S {
template<typename T>
std::enable_if_t<std::is_void<T>::value>
f() noexcept {}
template<typename T>
std::enable_if_t<not std::is_void<T>::value>
g() noexcept {}
};
正如预期的那样,编译:
s.f<void>();
这个不是:
s.g<void>();
令我困惑的是以下main
使用GCC(6.2)编译但不使用clang(3.9)编译:
int main() {
static_assert(noexcept(&S::f<void>), "!");
static_assert(noexcept(&S::g<void>), "!");
}
我会说第二个断言由于无效的专业化而失败。两位编译器对此意见不一。
哪个是正确的?
The set of potential exceptions of an expression e
is empty if e
is a
core constant expression (5.20).
也就是说,GCC 甚至不解析 template-id,因为它从一开始就知道结果是 true
(因为 g<void>
不是静态数据成员模板特化,其类型具有重载 operator&
)。虽然很聪明,但这种行为是不符合规范的,因为 template-id 的任何出现都需要将参数替换到函数模板的声明中。
考虑以下 class:
struct S {
template<typename T>
std::enable_if_t<std::is_void<T>::value>
f() noexcept {}
template<typename T>
std::enable_if_t<not std::is_void<T>::value>
g() noexcept {}
};
正如预期的那样,编译:
s.f<void>();
这个不是:
s.g<void>();
令我困惑的是以下main
使用GCC(6.2)编译但不使用clang(3.9)编译:
int main() {
static_assert(noexcept(&S::f<void>), "!");
static_assert(noexcept(&S::g<void>), "!");
}
我会说第二个断言由于无效的专业化而失败。两位编译器对此意见不一。
哪个是正确的?
The set of potential exceptions of an expression
e
is empty ife
is a core constant expression (5.20).
也就是说,GCC 甚至不解析 template-id,因为它从一开始就知道结果是 true
(因为 g<void>
不是静态数据成员模板特化,其类型具有重载 operator&
)。虽然很聪明,但这种行为是不符合规范的,因为 template-id 的任何出现都需要将参数替换到函数模板的声明中。