简体   繁体   English

部分专门化模板成员功能

[英]Partially specialize template member function

I have a template class which looks like the following: 我有一个模板类,如下所示:

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 what would be possible in a wonderful and ideal world where default template parameters and partial specialization of template methods are possible (without specializing the entire class). 你明显注意到我在一个美妙而理想的世界中写下了可能的东西,其中默认的模板参数和模板方法的部分特化是可能的(没有专门的整个类)。

I would like to ear about advices to achieve the same effect, that is, being able to have a specialized method for each size S so that I can select the proper pool to use. 我想了解建议以达到相同的效果,即能够为每个大小S设置一个专门的方法,以便我可以选择适当的池来使用。 I tried to add a get_pool<size_t> inside the pool_map, but almost the same problem happens: i can't specialize the inner class without specializing the outer one... 我试图在get_pool<size_t>添加一个get_pool<size_t> ,但几乎同样的问题发生了:我不能专门化内部类而不专门化外部类...

The only solution that comes to my mind, would be to use an outer get_pool<size_t> class that would take the pool_map as parameters an returns a reference to the poolX_ member, but I would like to avoid it, since it does not seems to be "the real static way". 我想到的唯一解决方案是使用外部get_pool<size_t>类,它将pool_map作为参数返回对poolX_成员的引用,但我想避免它,因为它似乎不是成为“真正的静态方式”。

Thanks for reading! 谢谢阅读!

There is one easy solution (maybe you didn't think about it), which is: 有一个简单的解决方案(也许你没有考虑过),这是:

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

But since this will maybe give you compilation errors (depending on what you put instead of "dispatch to ...") you could simply overload the get() function. 但是,由于这可能会给你编译错误(取决于你所放的而不是“dispatch to ...”)你可以简单地重载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.

The only problem is that the default implementation (if you need any) needs a condition like sizeof(T) * CHAR_BIT != 8 && sizeof(T) * CHAR_BIT != 16 && sizeof(T) * CHAR_BIT != 32 && sizeof(T) * CHAR_BIT != 64 唯一的问题是默认实现(如果你需要)需要像sizeof(T) * CHAR_BIT != 8 && sizeof(T) * CHAR_BIT != 16 && sizeof(T) * CHAR_BIT != 32 && sizeof(T) * CHAR_BIT != 64

The last solution (the best one I'd say) would still to use a private class with a static function which you can specialize (what you said was not the "real static way") 最后一个解决方案(我说的最好的解决方案)仍然会使用具有静态功能的私有类,您可以将其专门化(您所说的不是“真正的静态方式”)

One solution is the use of enable_if and disable_if (normally) though I haven't tested it. 一个解决方案是使用enable_ifdisable_if (通常),虽然我还没有测试过它。

Another solution is to simply forward the implementation details to a helper: 另一种解决方案是简单地将实现细节转发给帮助者:

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(); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM