C ++:模板专业化,标准映射选择错误的专业化

时间:2018-10-30 16:45:32

标签: c++ templates c++17 traits

我有一个模板,可以根据其stl类型调用其他模板。使用map <int, int>可以很好地工作,但是,如果我用map <int, std::string>调用专业化,它将选择通用专业化,而不是map专业化。如何确保任何类型的地图(<int, int><int, string>等)选择正确的专业化?

基本上看起来像这样,A类使用两个特征来专门化

template<typename T, typename P=trait<T>>
class A{
public
    typedef P traits
  //

    A(T a, T b){}

    static T foo(T a, T b){
        T d = traits::foo(a,b)
    }
};

特征:

template<typename T>
struct trait{
    static T foo(T a, T b){
        //do something
    }
};

template<typename T>
struct trait<std::map<T,T> >{
    static std::map<T,T> foo(std::map<T,T> a, std::map<T,T> b){
        //do something
    }
};

主要:

std::map<int, std::string> a = {{1,"a"},{2,"b"}}
std::map<int, std::string> b = {{3,"c"},{4,"d"}}
A some_name(a,b);
some_name.foo(a,b);

1 个答案:

答案 0 :(得分:1)

您可以对地图的键和值使用不同的模板参数:

template<typename K, V>
struct trait<std::map<K,V> >{
    static std::map<K,V> foo(std::map<K,V> a, std::map<K,V> b){
        //do something
    }
};

但是问题在于,使用自定义比较类或自定义分配器的映射将失败:

A<std::map<int, int>>  // specialization for std::map
A<std::map<int, float>> // specialization for std::map
A<std::map<int, float, std::greater<int>>> // generic. Oops.

因此,最好的选择实际上是使用可变参数模板进行专业化处理:

template<typename... Ts>
struct trait<std::map<Ts...> >{
    static std::map<Ts...> foo(std::map<Ts...> a, std::map<Ts...> b){
        //do something
    }
};