Partially specialize template member function

I have a template class that looks like this:

template <template <class TypeT> class PoolT=pool_base>
struct pool_map
{
public:
  template <typename U> struct pool { typedef PoolT<U> type };

public:
  template <typename T, size_t S=sizeof(T)>
  T& get( size_t index );

private:
  pool<uint8_t>::type  pool8_;
  pool<uint16_t>::type pool16_;
  pool<uint32_t>::type pool32_;
  pool<uint64_t>::type pool64_;
};

template <template <class TypeT> class PoolT>
template <typename T, size_t S>
inline
T& pool_map<PoolT>::get( size_t index )
{
  // Default case
}

template <template <class TypeT> class PoolT>
template <typename T>
inline
T& pool_map<PoolT>::get<T,8>( size_t index )
{
  // Dispatch to pool8_
}

template <template <class TypeT> class PoolT>
template <typename T>
inline
T& pool_map<PoolT>::get<T,16>( size_t index )
{
  // Dispatch to pool16_
}

template <template <class TypeT> class PoolT>
template <typename T>
inline
T& pool_map<PoolT>::get<T,32>( size_t index )
{
  // Dispatch to pool32_
}

You obviously noticed that I wrote that it would be possible in a beautiful and perfect world where default template parameters and partial specialization of template methods are possible (without specializing the entire class).

I would like to consult with tips on achieving the same effect, that is, be able to have a specialized method for each S size so that I can choose the right pool to use. I tried to add get_pool<size_t>pool_map inside, but almost the same problem occurs: I cannot specialize the inner class without specializing in the outer ...

, , - get_pool<size_t>, _map , poolX_, , " ".

!

+3
2

(, ):

template <typename T>
T& pool_map<PoolT>::get( size_t index )
{
  if (sizeof(T) * CHAR_BIT == 8) {
     // Dispatch to pool8_
  } else if (sizeof(T) * CHAR_BIT == 16) {
     // Dispatch to pool16_
  } else if (...) {
     ...
  } else {
    // Default case
  }
}

( , " ..." ), get().

template <typename T>
typename std::enable_if<sizeof(T) * CHAR_BIT == 8,T>::type&
    get( size_t index )
{
   ...
}

template <typename T>
typename std::enable_if<sizeof(T) * CHAR_BIT == 16,T>::type&
    get( size_t index )
{
   ...
}

etc.

, ( ) sizeof(T) * CHAR_BIT != 8 && sizeof(T) * CHAR_BIT != 16 && sizeof(T) * CHAR_BIT != 32 && sizeof(T) * CHAR_BIT != 64

(, ) , ( " " )

+3

enable_if disable_if (), .

:

namespace helper
{
  template <class T> struct getter { static void Do() {} };

  // specializations by type
}

template <class T>
T& pool_map<T>::get(size_t index) { return helper::getter<T>::Do(); }
0

Source: https://habr.com/ru/post/1759316/


All Articles