#c #templates #traits
#c #шаблоны #Трейты
Вопрос:
У меня есть следующий перечислитель:
enum class VariableType
{
Basic,
Vector2,
Vector3,
Vector4
};
и 3 шаблона векторного класса: Vector2, Vector3 и Vector4.
Я ищу функцию, используемую для инициализации переменных VariableType с помощью, передавая тип данных в параметре шаблона.
Например:
auto type1 = GetVariableType<float>::type; // type1 = VariableType::Basic
auto type2 = GetVariableType<Vector2<float> >::type; // type1 = VariableType::Vector2
Мне пришла в голову идея определить GetVariableType дважды, с разными шаблонами, но код не компилируется, когда я пишу второе определение ( std::enable_if_t::value>).
template<typename T, typename = std::enable_if_t<IsBasicType<T>::value>>
struct GetVariableType
{
static const VariableType type = VariableType::Basic;
};
template<typename T, typename = std::enable_if_t<IsVector2Type<T>::value>>
struct GetVariableType
{
static const VariableType type = VariableType::Vector2;
};
Есть какие-нибудь идеи, как я должен различать определения?
Ответ №1:
Не уверен, но мне кажется, что вы ищете что-то вроде
template<typename T>
struct GetVariableType
{ static constexpr VariableType type = VariableType::Basic; };
template<typename T>
struct GetVariableType<Vector2<T>>
{ static constexpr VariableType type = VariableType::Vector2; };
template<typename T>
struct GetVariableType<Vector3<T>>
{ static constexpr VariableType type = VariableType::Vector3; };
template<typename T>
struct GetVariableType<Vector4<T>>
{ static constexpr VariableType type = VariableType::Vector4; };
просто используя специализацию шаблона.
Предложение не по теме: избегайте указания имени type
переменной.
В стандартной библиотеке type-traits идентификатор type
обычно используется для определения (через a using
или a typedef
) типа, а не переменной.
Ответ №2:
Если вы хотите, чтобы это работало с переменными (как следует из названия вашего шаблона) вместо типов, тогда вы можете сделать:
template<typename T> VariableType GetVariableType (T) {return VariableType::Basic; };
template<typename T> VariableType GetVariableType (Vector2 <T>) { return VariableType::Vector2; };
template<typename T> VariableType GetVariableType (Vector3 <T>) { return VariableType::Vector3; };
template<typename T> VariableType GetVariableType (Vector4 <T>) { return VariableType::Vector4; };
И тогда вы можете сделать (например):
float f = 0;
auto type1 = GetVariableType (f);
std::cout << (int) type1 << 'n';
Vector2 <float> v2;
auto type2 = GetVariableType (v2);
std::cout << (int) type2 << 'n';
Выходной сигнал:
0
1