我有一个模板类,如下所示:
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_
}
您显然注意到我在一个精彩而理想的世界中写下了可能的内容,其中默认模板参数和模板方法的部分特化是可能的(没有专门化整个类)。
我想了解建议以达到相同的效果,即能够为每个大小S设置专门的方法,以便我可以选择适当的池来使用。我试图在pool_map中添加一个get_pool<size_t>
,但几乎同样的问题发生了:我不能专门化内部类而不专门研究外部类...
我想到的唯一解决方案是使用外部get_pool<size_t>
类,它将pool_map作为参数返回对poolX_
成员的引用,但我想避免它,因为它似乎不是“真正的静态方式”。
感谢阅读!
答案 0 :(得分:3)
有一个简单的解决方案(也许你没有考虑过),这是:
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
}
}
但是,由于这可能会给你编译错误(取决于你放置的内容而不是“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.
唯一的问题是默认实现(如果您需要)需要像sizeof(T) * CHAR_BIT != 8 && sizeof(T) * CHAR_BIT != 16 && sizeof(T) * CHAR_BIT != 32 && sizeof(T) * CHAR_BIT != 64
这样的条件
最后一个解决方案(我说的最好的解决方案)仍然会使用一个静态函数的私有类,你可以专门化(你说的不是“真正的静态方式”)
答案 1 :(得分:0)
一种解决方案是使用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(); }