【问题标题】:Having a Template take either a Type or a value让模板采用类型或值
【发布时间】:2019-04-02 10:50:25
【问题描述】:

我想创建一个 MemoryPool 以在运行时动态分配和取消分配内存,而不涉及操作系统,以尝试加速代码执行(和学习)。为了简化语法,我希望能够将内存段的大小指定为它们包含的类型或原始大小。

为此,我想制作一个模板,它可以采用 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)> { };

我希望上面的 sn-p 发生的事情是

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

打印 5 和 sizeof(int)。

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

【问题讨论】:

  • 您需要一个 C++17 编译器,并使用 auto 模板参数。
  • @SamVarshavchik 什么不能解决问题,因为它只接受值
  • 模板没有“重载”。
  • 对了,为什么不能只使用size_t变体,在实例化模板时直接显式使用sizeof(int)

标签: c++ templates


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    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。

    【讨论】:

    • 这很简洁,很可能我最终会做。但是在尝试使用该类时会产生一些歧义。
    猜你喜欢
    • 2022-01-11
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多