C ++: специализация шаблонов, неправильная специализация на стандартной карте - PullRequest
0 голосов
/ 30 октября 2018

У меня есть шаблон, который вызывает другие шаблоны в зависимости от их типа stl. Использование карты <int, int> работает нормально, однако, если я вызываю специализацию с картой <int, std::string>, выбирается общая специализация, а не специализация карты. Как я могу убедиться, что на картах любого типа (<int, int>, <int, string> и т. Д.) Выбрана правильная специализация?

В основном это выглядит так, класс А использует две черты специализации

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 голосов
/ 30 октября 2018

Вы можете использовать различные параметры шаблона для ключа и значения карты:

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
    }
};
...