TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.34K subscribers
Post #186 1.91K
​Объединения условий в enable_if

Иногда мы хотим сильно ограничить свойства типов, с которыми мы хотим инстанцировать шаблон. Например, тип должен быть default-constructed и иметь оператор сравнения. У нас есть для этого метафункция std::enable_if, которая позволяет нам проверять наличие свойств у типов. Но вот незадача, как проверить два условия одновременно? Я хочу и то, и то.

Ранее для этого использовались обычные операторы && и || между тайптрейтами.

Однако в С++17 появились специальные метаклассы, которые позволяют комбинировать условия. Это

• template<class... B> struct conjunction; - логическое И
• template<class... B> struct disjunction; - логическое ИЛИ
• template<class B> struct negation; - логичесткое НЕ

Эти трейты имеют подходящие осмысленные имена, поэтому их использование повышает читаемость кода.

Например, вы можете сочетать эти метафункции с variadic шаблонами
Тогда может появиться что-то такое:

template<typename... Ts>
std::enable_if_t<std::conjunction_v<std::is_same<int, Ts>...>> PrintIntegers(Ts ... args)
{
(std::cout << ... << args) << 'n';
}


В функцию PrintIntegers мы можем передать сколько угодно(почти) аргументов и все они будут проверяться на соответствие целочисленному типу

Или например вы хотите принтовать только числа? Тогда мы идем к вам:

template<typename T, typename = std::enable_if_t<std::disjunction_v<std::is_integral<T>, std::is_floating_point<T>>>>
void PrintValue(T value)
{
std::cout << "Value: " << value << std::endl;
}


Если тип - не целочисленный и не с плавающей точкой, то такая перегрузка будет отбрасываться.

Ну и например вы хотите, чтобы функция для вывода в консоль не принимала аргумент-указатель. Тоже можно сделать.

template<typename T, typename = std::enable_if_t<std::negation_v<std::is_pointer<T>>>> 
void PrintValue(T value)
{
std::cout << "Value: " << value << std::endl;
}


Такие вот удобные метафункции.

Create complex conditions. Stay cool.

#cpp17 #template
  • 👍 22
  • 🔥 8
  • ❤ 4
  • 😁 2
  • 🌭 1
More from @grokaemcpp
  1. Oct 17, 2026Оптимистичные и пессимистичные блокировки #опытным Концепция блокировок уходит далеко за п…
  2. Oct 14, 2026​​Что внутри std::condition_variable? #опытным Более менее все знакомы с примитивом синхро…
  3. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  4. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  5. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  6. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →