#c #c -concepts
Вопрос:
Часто (большую часть времени?) при создании типов с параметрами типа шаблона вы хотите убедиться, что параметр типа заполнен без ссылки, неквалифицированным (неконстантным, энергонезависимым) типом. Однако простое определение, подобное приведенному ниже, позволяет пользователю вводить любой тип для T
:
template <typename T>
class MyContainer {
T* whatever;
T moreStuff;
};
В современном C есть концепции, которые должны быть способны решить эту проблему. Каков наилучший (и желательно наименее шаблонный) способ сделать это?
Ответ №1:
static_assert
это хороший вариант:
#include <type_traits>
template <typename T>
class MyContainer
{
static_assert(!std::is_reference_v<T>);
static_assert(!std::is_const_v<T>);
static_assert(!std::is_volatile_v<T>);
T* whatever;
T moreStuff;
};
Ответ №2:
Я бы использовал для этого концепцию.
template <typename T>
concept cvref_unqualified = std::is_same_v<std::remove_cvref_t<T>, T>;
template <cvref_unqualified T>
class MyContainer {...};
Комментарии:
1. Хотя для меня концепция должна иметь «значение». Особенно когда мы имеем в виду правила подчинения.
2. @Jarod42, возможно, стандартные концепции имеют ту же проблему, например
derived_from
. Но да, ОП мог бы обернуть эту концепцию чем-то вродеconcept MyContainerElement
…3. Здесь мы также имеем композицию из нескольких черт, которая не отражена в концепции. и следует провести размышление (OP, в зависимости от потребностей), чтобы узнать, следует ли разделять эту концепцию или не допускать ее включения.
Ответ №3:
Вы можете проверить тип с помощью static_assert
like
template <typename T>
class MyContainer {
static_assert(std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, T>, "T must be non-reference, unqualified type");
T* whatever;
T moreStuff;
};