此问题紧接此问题:Function overloading and template deduction priority
考虑以下类:
template<typename T1, typename T2>
class Base {};
class Derived0 : public Base<double, double> {};
template<typename T1, typename T2, typename T3>
class Derived1 : public Base<T1, T2> {};
template<typename T1, typename T2, typename T3, typename T4>
class Derived2 : public Base<T3, T4> {};
以及以下功能:
template<typename T> f(const T& x); // version A
template<typename T1, typename T2> f(const Base<T1, T2>& x); // version B
我的问题是f(double)
会打电话version A
(好的),f(Base<double, double>)
会打电话version B
(好的),但是f(Derived1<double, double, double>)
会打电话version A
(请参阅开头的另一个问题的链接)。
使用C++11,如何阻止version A
和力version B
对于 Base<T1, T2>
的所有派生成员无论如何T1
和T2
是?
注意:如果可能,我想避免添加辅助类,而更喜欢向提供的类添加成员。
最佳答案
这是一个可能适合您的特征。
特征类别:
#include <type_traits>
template <typename, typename> struct Base { };
template <typename T> struct isbase
{
typedef char yes;
typedef yes no[2];
template <typename U, typename V> static yes & test(Base<U, V> const &);
static no & test(...);
static bool const value = sizeof(test(std::declval<T>())) == sizeof(yes);
};
应用:
#include <iostream>
template <typename T>
typename std::enable_if<!isbase<T>::value>::type f(T const &)
{
std::cout << "f(T const &)\n";
}
template <typename T1, typename T2>
void f(Base<T1, T2> const &)
{
std::cout << "f(Base<T1, T2> const &)\n";
}
示例:
template<typename T1, typename T2, typename T3>
struct Derived1 : public Base<T1, T2> {};
int main()
{
std::cout << isbase<double>::value << std::endl;
std::cout << isbase<Base<int, char>>::value << std::endl;
std::cout << isbase<Derived1<bool, bool, bool>>::value << std::endl;
f(double{});
f(Base<int, char>{});
f(Derived1<bool, float, long>{});
}
泛化:我们可以创建一个更通用的特征来检查类型是否派生自模板实例:
template <typename T, template <typename...> class Tmpl>
struct derives_from_template
{
typedef char yes;
typedef yes no[2];
template <typename ...Args> static yes & test(Tmpl<Args...> const &);
static no & test(...);
static bool const value = sizeof(test(std::declval<T>())) == sizeof(yes);
};
用法:derives_from_template<T, Base>::value
等等
关于c++ - 阻止所有模板化派生类型的通用模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13901964/