我正在尝试编写一个函数模板。一个版本应该用于不满足另一版本标准的所有类型;当参数是给定类的基类或该类本身时,应使用另一个版本。
我尝试过超载Base&
,但是当类派生自Base
,他们使用通用的,而不是特定的。
我也尝试过这种 SFINAE 方法:
struct Base { };
struct Derived : public Base { };
struct Unrelated { };
template<typename T>
void f(const T& a, bool b = true) {
cout << "not special" << endl;
}
template<typename T>
void f(const Base& t, bool b = is_base_of<Base, T>::value) {
cout << "special" << endl;
}
Base b;
Derived d;
Unrelated u;
f(b); f(d); f(u);
但它们都打印“不特别”。我不擅长 SFINAE,我可能只是做错了。我怎样才能写一个这样的函数?
首先,这些都不会被称为“特殊”f
超载,因为T
不能从函数参数推导出来。它的第一个参数必须是类型T
:
void f(const T& t, bool b = is_base_of<Base, T>::value)
完成后,请注意“特殊”重载并不真正使用 SFINAE 来影响重载解析:is_base_of<T, U>::value
总是有一个值:要么是true
or false
。要影响重载解析,您需要使用enable_if
,它根据布尔值有条件地定义类型。
此外,两个重载都需要使用 SFINAE:如果满足以下条件,则必须启用“特殊”重载:T
是从基派生的(或者是基类型),并且只有在以下情况下才必须启用“非特殊”重载:T
不是从基派生的,否则会出现重载解析歧义。
这两个重载应声明并定义为:
template<typename T>
void f(T const& a, typename enable_if<!is_base_of<Base, T>::value>::type* = 0)
{
cout << "not special" << endl;
}
template<typename T>
void f(T const& t, typename enable_if<is_base_of<Base, T>::value>::type* = 0)
{
cout << "special" << endl;
}
最后,请注意,这里没有专门化。这两个函数名为f
are 超载.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)