让模板采用类型或值

时间:2019-04-02 10:50:26

标签: c++ templates types

我想创建一个MemoryPool来在运行时动态分配和取消分配内存,而无需让OS尝试加快代码执行(和学习)的速度。为了简化语法,我希望能够以内存段的类型或原始大小来指定内存段的大小。

为此,我想制作一个可以使用Type或size_t并继续发送sizeof Type或size的模板。

template<size_t SegmentSize>
class MemoryPool_Internal
{
public:
    static const size_t Size = SegmentSize;
    /*Using SegmentSize to do logic*/
};

template<size_t Size>
class MemoryPool : public MemoryPool_Internal<Size> { };

template<class Size>
class MemoryPool : public MemoryPool_Internal<sizeof(Size)> { };

我希望上面的代码片段发生

std::cout << MemoryPool<5>::Size << std::endl;
std::cout << MemoryPool<int>::Size << std::endl;

要打印5和sizeof(int)。

但是5会引发C3855,因为它不是一个类;而int会引发E0254,因为第一个模板中不允许使用类型。 有什么方法可以在编译时解决每个目标模板的问题?

2 个答案:

答案 0 :(得分:8)

您不能完全那样做。该语言不允许这种语法。但是,您只能使用类型模板并创建一个类型来保留显式大小:

template <std::size_t SegmentSize>
struct ExplicitSize
{
    static constexpr auto Size = SegmentSize;
};

template <class T>
constexpr std::size_t SegmentSize = sizeof(T);
template <std::size_t Size>
constexpr std::size_t SegmentSize<ExplicitSize<Size>> = Size;


template<class SizeSpecifier>
class MemoryPool_Internal
{
public:
    static const size_t Size = SegmentSize<SizeSpecifier>;
    /*Using Size to do logic*/
};

static_assert(MemoryPool_Internal<ExplicitSize<32>>::Size == 32);
static_assert(MemoryPool_Internal<int>::Size == sizeof(int));

或者,仅使用值模板,并使用sizeof

MemoryPool_Internal<32>
MemoryPool_Internal<sizeof(int)>

答案 1 :(得分:1)

您的问题源于试图为两个不同的模板类使用相同的名称。

我认为,这里唯一的解决方案是为不同类型的内存池使用不同的名称(我认为稍后阅读代码时,模棱两可):

template< size_t SIZE >
class MemoryPool_Internal
{
public:
    static const size_t Size = SIZE;
    /*Using SegmentSize to do logic*/
};

template< size_t SIZE >
class SizedMemoryPool : public MemoryPool_Internal< SIZE > { };

template< typename TYPE >
class TypedMemoryPool : public MemoryPool_Internal< sizeof( TYPE )> { };

以上对我有用-为您的测试分别输出5和4。