noexcept运算符和enable_if_t:它们一起工作吗?

时间:2016-10-19 21:19:31

标签: 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 {}
};

正如所料,这编译:

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>), "!");
}

我会说第二个断言失败是因为无效的专业化。两位编制者对此持不同意见。

哪一个是正确的?

1 个答案:

答案 0 :(得分:3)

[except.spec]/13

  

如果e为a,则表达式e的潜在异常集为空   核心常数表达式(5.20)。

也就是说,GCC甚至不解析 template-id ,因为它从一开始就知道结果是true(因为g<void>不是静态数据成员模板特化,其类型具有重载operator&)。虽然聪明,但行为是不一致的,因为任何出现的 template-id 都需要将参数替换为函数模板的声明。