c++ std::enable_if中具有常数值的类专门化

qqrboqgw  于 2023-02-14  发布在  其他
关注(0)|答案(1)|浏览(263)

当模板参数从特定类型派生时,我正在为类编写部分特化。我的实现如下-

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的参数必须依赖于模板参数?

ccrfmcuu

ccrfmcuu1#

为什么SFINAE不踢在这里?
SFINAE代表“substitution failure is not a error"。如果std::enable_if的参数不是依赖的,那么就没有替换,所以它不适用是有道理的。
具体来说,该标准指出程序是病态的,不需要诊断,如果
一个假设的模板示例化紧跟在它的定义之后,由于一个不依赖于模板参数的结构,它将是病态的,[...]
(from C++20后草案N4868的[一般临时决议]/8.4)
std::enable_if<false>::type不依赖于模板定义,并且紧跟在模板定义之后。

相关问题