Самая первая вещь, с которой у меня возникает «проблема», это bool
литерал (true
/ false
).Я понимаю, что они верны, и шаблоны могут принимать значения констант во время компиляции примитивных типов данных (простые-старые типы данных), но если бы мне было поручено разработать enable_if
"механизмы" вместо использования true
/ false
Я хотел бы создать классы тегов true_t
(или True
) и false_t
(или False
) следующим образом
Проблема с использованием типа тега вместо просто bool заключается в том, чтоВы должны добавить дополнительную сложность к коду.Если вы хотите проверить условие времени компиляции, например, sizeof
, вы не можете просто выполнить sizeof(T) == 8
.Вам придется создать абстракцию, которая выполняет проверку и возвращает соответствующий тип тега.
Второе, что я считаю избыточным, - это необходимость указать typename T
параметр шаблона.Не было бы проще / лучше просто реализовать enable_if
следующим образом
Не совсем.Что если вы хотите использовать SFINAE для типа возвращаемого значения?Тогда у вас будет только функция void, которая неоправданно ограничивает.Вместо этого вы можете использовать то, что позже было добавлено в C ++ 14 и C ++ 17, и создавать псевдонимы.Это делает имена не зависимыми и позволяет отбрасывать typename
template< bool B, class T = void >
using enable_if_t = typename enable_if<B,T>::type;
template< class T >
inline constexpr bool is_integral_v = is_integral<T>::value;
Это позволяет вам переписать
template <class T,
typename std::enable_if<std::is_integral<T>::value,T>::type* = nullptr>
void do_stuff(T& t) { /* do stuff */ };
в
template <class T,
std::enable_if_t<std::is_integral_v<T>,T>* = nullptr>
void do_stuff(T& t) { /* do stuff */ };
, хотя я предпочитаюиспользовать bool для типа enable_if_t
типа
template <class T,
std::enable_if_t<std::is_integral_v<T>, bool> = true>
void do_stuff(T& t) { /* do stuff */ };
Я знаю, что на этом сайте я обязан задать один вопрос в пределах ... одного "поста вопроса-подобный »формат, но если вы сочтете его приемлемым, могу ли я также спросить, чего достигнет этот синтаксис:
std::enable_if</* ... */>::type* = nullptr
?
Создает указатель на тип, который std::enable_if
"возвращает", и устанавливает его в нулевой указатель.Цель здесь - создать параметр шаблона, который будет существовать, только если условие истинно.Вы можете переписать его в
typename = typename std::enable_if</* ... */>::type
, чтобы вместо параметра без типа у вас был параметр типа.Оба они выполняют одно и то же, но последние не работают с перегрузкой функции для разных enable_if
, поскольку параметры шаблона по умолчанию не являются частью сигнатуры.Первая версия, которая использует параметры не-типа, включена в сигнатуру функции и позволяет вам перегружать enable_if
.