Наличие шаблона принимает либо тип, либо значение - PullRequest
3 голосов
/ 02 апреля 2019

Я хочу, чтобы MemoryPool динамически назначал и отменял назначение памяти во время выполнения без вовлечения ОС в попытку ускорить выполнение кода (и учиться).Чтобы просто описать синтаксис, я хотел бы иметь возможность указывать размер сегментов памяти в качестве типа, который они содержат, или в виде необработанного размера.

Для этого я хочу создать шаблон, который может принимать либоВведите или size_t и отправьте вперед либо sizeof Type, либо размер.

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 ]

8 голосов
/ 02 апреля 2019

Вы не можете сделать это в точности так. Язык не допускает такой синтаксис. Однако вы можете использовать только шаблоны типов и создать тип для хранения явного размера:

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 голос
/ 02 апреля 2019

Ваша проблема связана с попыткой использовать одно и то же имя для двух разных шаблонных классов.

Использование разных имен для разных типов пула памяти - единственное решение, я думаю (и, на мой взгляд, менее неоднозначно)при чтении кода позже):

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 для вашего теста соответственно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...