c++ - 阻止所有模板化派生类型的通用模板函数

标签 c++ templates c++11 metaprogramming overloading

此问题紧接此问题: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> 的所有派生成员无论如何T1T2是?

注意:如果可能,我想避免添加辅助类,而更喜欢向提供的类添加成员。

最佳答案

这是一个可能适合您的特征。

特征类别:

#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/

相关文章:

c++ - vector n 维 vector 本身具有特定的数据类型

c++ - 运行时错误 : map/set iterators incompatible

c++ - 我如何在不知道他有哪些构造函数的情况下初始化属性?

c++ - 模板向后兼容 gcc 4.7

c++ - Boost.Compute 比普通 CPU 慢?

c++ - 对类型的非常量左值引用无法绑定(bind)错误

用于类型和非类型模板的 c++ auto

c++ - 由其他模板类的内部 typedef 定义的类型的模板参数

c++ - 从变化的区间有效地生成伪随机整数

c++ - 区分分配在栈上的对象和堆对象