过去,当使用 SFINAE 选择构造函数重载时,我通常使用以下内容:
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 http://coliru.stacked-crooked.com/a/64a1aaf13ce6099b
我之前的回答是错误的。对不起。我只是要修复它。
本声明:
template <typename U = T, void...>
Class() { }
违反[temp.res]/8:
该计划是
格式错误,不需要诊断,如果 [...] 可变参数模板的每个有效特化都需要空模板参数包
它不需要诊断,但编译器无论如何都会选择发出诊断。无论哪种方式,代码都是格式错误的。
另一方面
template <typename U = T, std::enable_if_t<std::is_void<U>::value>...>
Class() { }
不违反此要求。我们有一个空包,所以我们不会因为您无法使用而发生冲突void
作为非类型模板参数。此外,假设的专业化enable_if
可以提供一个不是的类型void
因此,由于上述限制,它不会格式错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)