在 SFINAE 中使用省略号是如何工作的?

How does using ellipses for SFINAE work?

过去使用 SFINAE select 构造函数重载时,我通常使用以下内容:

template <typename T>
class Class {
public:
    template <typename U = T, typename std::enable_if<std::is_void<U>::value, int>::type=0>
    Class() {
        std::cout << "void" << std::endl;
    }

    template <typename U = T, typename std::enable_if<!std::is_void<U>::value, int>::type=0>
    Class() {
        std::cout << "not void" << std::endl;
    }
};

但是,我刚刚遇到了这个替代方案:

template <typename U = T, typename std::enable_if<std::is_void<U>::value>::type...>
Class() {
    std::cout << "void" << std::endl;
}

考虑到以下内容不合法...

template <typename U = T, void...> // ERROR!
Class() { }

...上面使用省略号而不是非类型模板参数的替代方法如何工作?


完整代码:http://coliru.stacked-crooked.com/a/64a1aaf13ce6099b

我之前的回答是错误的。对不起。我只是要修复它。


此声明:

template <typename U = T, void...>
Class() { }

违反[temp.res]/8:

The program is ill-formed, no diagnostic required, if [...] every valid specialization of a variadic template requires an empty template parameter pack

不需要诊断,但编译器还是选择发出一个。无论哪种方式,代码都是错误的。

另一方面

template <typename U = T, std::enable_if_t<std::is_void<U>::value>...>
Class() { }

不违反此要求。我们有一个空包,所以我们不会 运行 与不能使用 void 作为非类型模板参数这一事实相冲突。此外,enable_if 的假设特化可以提供 void 不存在的类型,因此由于上述限制,它不是格式错误的。