Почему type_traits реализован с использованием структур - PullRequest
1 голос
/ 20 октября 2019

Большинство черт типов создаются с использованием частичной (или полной) специализации struct и template. Например, std::is_same реализован как

template<typename>
struct is_same : false_type {};
template<typename T>
struct is_same<T, T> : true_type {}; // partial specialization

Использование будет

bool are_equal = std::is_same<T, U>::value;

или

.. = std::is_same_v<T, U>;

, что несколько уродливо. Сначала я думал, что это единственное решение, потом я обнаружил, что переменные также могут быть частично специализированными (а функции - нет). Черты преобразования типов не могут (явно) быть переменными, но для «информационных» черт, почему это не будет лучше, чем структура?

template<typename>
inline constexpr bool is_same = false;
template<typename T>
inline constexpr bool is_same<T, T> = true;

А затем

bool are_equal = std::is_same<T, U>;

Ответы [ 3 ]

2 голосов
/ 20 октября 2019

Причина просто историческая. Большинство черт типов были добавлены в библиотеку первыми, в C ++ 11. Шаблоны переменных были добавлены позже в C ++ 14, и изменить точку реализации было невозможно, поскольку это слишком обратно несовместимо. Поэтому были добавлены переменные с суффиксом _v, и это стало соглашением.

Новые черты добавляются одинаково, потому что важно иметь согласованность в любой библиотеке, не говоря уже о стандартной библиотеке.

0 голосов
/ 20 октября 2019

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

0 голосов
/ 20 октября 2019

Иногда вам нужен тип, а не просто базовое значение bool. Простой пример представлен техникой отправки тегов:

void foo(std::true_type)  { ... }
void foo(std::false_type) { ... }

foo(std::is_same<T, S>{});

Если бы std::is_same был просто шаблоном переменной bool, этот код не был бы таким элегантным.

...