400 8949 560

NEWS/新闻

分享你我感悟

您当前位置> 主页 > 新闻 > 技术开发

c++中的std::conjunction和std::disjunction是什么_c++模板元编程逻辑运算【C++17】

发表时间:2026-01-01 00:00:00

文章作者:冰火之心

浏览次数:

std::conjunction和std::disjunction是C++17引入的编译期逻辑“与”“或”工具,接受类型参数(如std::true_type或类型特征),支持短路求值;配合std::negation可简洁表达复杂约束,提升SFINAE和concept-like条件的可读性与实用性。

std::conjunctionstd::disjunction 是 C++17 引入的模板元编程工具,用于在编译期对多个类型特征(如 std::is_integral_v)或布尔常量进行逻辑“与”和逻辑“或”运算。

它们本质是编译期布尔值的折叠

这两个类模板不是函数,而是可变参数模板别名,内部利用模板偏特化实现短路语义(类似运行时 && / || 的行为):

  • std::conjunction:当所有模板参数 Bi 都是 std::true_type(即其 ::valuetrue)时,整个表达式为 true;任意一个为 false,立即得 false(不实例化后续)。
  • std::disjunction:只要有一个 Bistd::true_type,结果就是 true;全为 false 才得 false;遇到第一个 true 就停止(短路)。

使用场景:简化 SFINAE 和约束条件

以前写多个 std::enable_if_t 嵌套很麻烦,现在可以直接组合判断:

  • 比如要求类型 T 同时是整型、有默认构造、且可复制:
template
std::enable_if_t,
    std::is_default_constructible_v,
    std::is_copy_constructible_v
>> foo() { /* ... */ }
  • 又如:允许传入任意一个支持 size()length() 成员的类型:
template
std::enable_if_t,
    std::is_member_function_pointer_v
>> bar(const T& t) { /* ... */ }

注意:参数必须是类型,不是布尔值字面量

你不能直接写 std::conjunction —— 这会编译失败。必须传入满足 std::bool_constant<...> 接口的类型,比如:

  • ✅ 正确:std::conjunction<:true_type std::is_same int>>
  • ✅ 更常用(C++17 起推荐):std::conjunction_v<:is_integral>, std::is_signed>_v 后缀是 value 的变量模板)
  • ❌ 错误:std::conjunction>true 不是类型)

还有 std::negation:逻辑非

虽然没在标题里提,但它常和前两者搭配使用:

  • std::negation<:is_void>>::value 等价于 !std::is_void_v
  • std::negation_v<:is_reference>> 更简洁

它也支持短路(单参数,意义不大),但语义清晰、可读性好。

基本上就这些。它们不复杂,但让模板约束更接近自然语言逻辑,避免深层嵌套和手写特化,是现代 C++ 元编程的实用基础工具。

相关案例查看更多