TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #189 2.05K
​std::conjunction vs &&

Вчера мы поговорили о том, что инстанцирование в std::conjunction и std::disjunction происходит по короткой схеме. Как только мы нашли шаблонный аргумент, для которого будет валидно выражение bool(Bi::value) == false, инстанциация остальных аргументов прекращается и выводится тип std::conjunction::value.

Однако при инстанциации шаблонов операторы && и || не могут похвастаться наличием короткой схемы. Что в форме fold expression, что в явной последовательной форме. То есть

template <class T>
struct type_without_value
{
};

template <class T1, class T2>
constexpr auto numbers = (std::is_integral_v<T1> && type_without_value<T2>::value);

constexpr auto result = numbers<float, int>;


компиляция вот этого кода закончится с ошибкой error: value is not a member of type_without_value<int>. Хотя float - совсем не интергральный тип и при работающей короткой схеме вычислений, ошибки компиляции не было бы. Потому что второй тип даже не инстанцировался бы. Как в случае с std::conjunction.

template <typename T>
struct valid_except_void : std::false_type
{
};

template <>
struct valid_except_void<void>
{
};

template <class T1, class T2>
constexpr auto test = std::conjunction_v<valid_except_void<T1>, valid_except_void<T2>>;

constexpr auto result = test<float, void>;


Такой код успешно скомпилируется и result будет равен false. Потому что инстанциация первого шаблона valid_except_void<T1> завершится успешно и для него bool(value) == false. Поэтому validexceptvoid с войдом не испортит нам игру.

То есть преимущество std::conjunction в том, что как только мы нашли его аргумент, для которого bool(value) == false, то все последующие аргументы не инстанцируются. Это может быть полезно, когда последующие типы очень затратные при инстанцировании или могут вызвать фатальные ошибки, если их инстанцировать с неправильным типом.

Прошу прощение за частое употребление слова "инстанцировать". Я просто не знаю нормального аналога/синонима. Кто знает, поделитесь в комментах.

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

Always compare your tools. Stay cool.

#template #cpp17
  • 🔥 13
  • 👍 5
  • ❤ 4
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 →