在 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() { }
...上面使用省略号而不是非类型模板参数的替代方法如何工作?
我之前的回答是错误的。对不起。我只是要修复它。
此声明:
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
不存在的类型,因此由于上述限制,它不是格式错误的。
过去使用 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() { }
...上面使用省略号而不是非类型模板参数的替代方法如何工作?
我之前的回答是错误的。对不起。我只是要修复它。
此声明:
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
不存在的类型,因此由于上述限制,它不是格式错误的。