Template and overloads
template<class Key1, class Key2, class Type> class DualMultimapCache
{
public:
std::list<std::reference_wrapper<Type>> get(Key1 const & key);
std::list<std::reference_wrapper<Type>> get(Key2 const & key);
template<class ...Args> Type & put(Key1 const & key, Args const & ...args);
template<class ...Args> Type & put(Key2 const & key, Args const & ...args);
};
Here, I have a public interface for a class. Underlying data structures don't matter. Everything will work just fine when Key1
and Key2
are of different types. If they end up being the same type, the overloads will likely be impossible. Am I right thinking this?
If I am, is there a way to separate the overloads while keeping the signature as clean as possible?
EDIT: Here a more in depth sample
template<class Key1, class Key2, class Type> class DualMultimapCache
{
public:
std::list<std::reference_wrapper<Type>> get(Key1 const & key);
std::list<std::reference_wrapper<Type>> get(Key2 const & key);
template<class ...Args> Type & put(Key1 const & key, Args const & ...args);
template<class ...Args> Type & put(Key2 const & key, Args const & ...args);
private:
std::unordered_multimap<Key1, std::reference_wrapper<Type>> map_Key1;
std::unordered_multimap<Key2, std::reference_wrapper<Type>> map_Key2;
};
template<class Key1, class Key2, class Type>
std::list<std::reference_wrapper<Type>> DualMultimapCache<Key1, Key2, Type>::get(Key1 const & key)
{
auto its = map_Key1.equal_range(key);
if (its.first == map.cend() && its.second == map.cend())
throw std::out_of_range();
else
return { its.first, its.second };
}
template<class Key1, class Key2, class Type>
std::list<std::reference_wrapper<Type>> DualMultimapCache<Key1, Key2, Type>::get(Key2 const & key)
{
auto its = map_Key2.equal_range(key);
if (its.first == map.cend() && its.second == map.cend())
throw std::out_of_range();
else
return { its.first, its.second };
}
对于相同密钥类型的情况,您可以部分专门化模板,例如
template <typename Key, typename Type>
class DualMultimapCache<Key, Key, Type>
{
public:
std::list<std::reference_wrapper<Type>> get(Key const & key);
template<class ...Args> Type & put(Key const & key, Args const & ...args);
};
I think you have to use partial specialization with 2 parameters, but it is not convenient because you have to use slightly different interface. To solve this problem I suggest using SFINAE
template<typename Key1, typename Key2, typename Type,
typename Enable = void > class DualMultimapCache
{
public:
std::list<std::reference_wrapper<Type>> get(Key1 const & key);
std::list<std::reference_wrapper<Type>> get(Key2 const & key);
template<class ...Args> Type & put(Key1 const & key, Args const & ...args);
template<class ...Args> Type & put(Key2 const & key, Args const & ...args);
};
template<typename Key1, typename Key2, typename Type > class DualMultimapCache < Key1, Key2, Type,
typename std::enable_if<std::is_same<Key1, Key2>::value>::type >
{
public:
std::list<std::reference_wrapper<Type>> get(Key1 const & key);
template<class ...Args> Type & put(Key1 const & key, Args const & ...args);
};
And you can use single interface with 3 template parameters but getting different specializations:
DualMultimapCache<int, double, int> t1; // DualMultimapCache template impl
DualMultimapCache<int, int, int> t2; // DualMultimapCache template
// specialization impl
链接地址: http://www.djcxy.com/p/40990.html
上一篇: 了解ShinyServer上托管的RShiny应用程序的可伸缩性
下一篇: 模板和重载