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

我会说第二个断言由于无效的专业化而失败。两位编译器对此意见不一。

哪个是正确的?

[except.spec]/13:

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 的任何出现都需要将参数替换到函数模板的声明中。