当模板参数从特定类型派生时,我正在为类编写部分特化。我的实现如下-
struct base {};
struct derived: public base {};
template <typename T, typename=void>
struct foo {
foo() { std::cout << "Version 1" << std::endl; }
};
template <typename T>
struct foo <T, typename std::enable_if<std::is_base_of<base, T>::value>::type> {
foo() { std::cout << "Version 2" << std::endl; }
};
这和预期的一样-当我示例化foo<int>
时,构造函数输出Version 1
,当我示例化foo<derived>
时,构造函数输出Version 2
。
我在测试一些东西,想禁用部分特化,所以我就把它改成了-
template <typename T>
struct foo <T, typename std::enable_if<false>::type> {
foo() { std::cout << "Version 2" << std::endl; }
};
我刚刚用常量false
替换了std::is_base_of<base, T>::value
,但是这次编译器开始发出警告,比如std::enable_if<false, void>
没有type
。
为什么它会有这样的行为?为什么SFINAE在这里不起作用?为什么std::enable_if
的参数必须依赖于模板参数?
1条答案
按热度按时间ccrfmcuu1#
为什么SFINAE不踢在这里?
SFINAE代表“substitution failure is not a error"。如果
std::enable_if
的参数不是依赖的,那么就没有替换,所以它不适用是有道理的。具体来说,该标准指出程序是病态的,不需要诊断,如果
一个假设的模板示例化紧跟在它的定义之后,由于一个不依赖于模板参数的结构,它将是病态的,[...]
(from C++20后草案N4868的[一般临时决议]/8.4)
std::enable_if<false>::type
不依赖于模板定义,并且紧跟在模板定义之后。