sky*_*ack 5 c++ gcc clang language-lawyer noexcept
考虑以下课程:
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 {}
};
Run Code Online (Sandbox Code Playgroud)
正如所料,这编译:
s.f<void>();
Run Code Online (Sandbox Code Playgroud)
这个不是:
s.g<void>();
Run Code Online (Sandbox Code Playgroud)
让我感到困惑的是,以下内容main与GCC(6.2)编译并且不使用clang(3.9)进行编译:
int main() {
static_assert(noexcept(&S::f<void>), "!");
static_assert(noexcept(&S::g<void>), "!");
}
Run Code Online (Sandbox Code Playgroud)
我会说第二个断言因为无效的专门化而失败了.两位编制者对此持不同意见.
哪一个是正确的?
e如果表达式e是核心常量表达式 (5.20),则该表达式的潜在异常集为空。
也就是说,GCC 甚至不解析template-id,因为它从一开始就知道结果是true(因为g<void>不是类型具有重载的静态数据成员模板专业化operator&)。虽然很聪明,但这种行为是不符合标准的,因为任何出现template-id 都需要将参数替换到函数模板的声明中。