C++中的std::conjunction和std::disjunction是什么

来源:Java编程网作者:半糖头衔:草根站长
导读:本期聚焦于小伙伴创作的《C++中的std::conjunction和std::disjunction是什么》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++中的std::conjunction和std::disjunction是什么》有用,将其分享出去将是对创作者最好的鼓励。

在C++17引入的模板元编程工具中,std::conjunction和std::disjunction是用于编译期逻辑运算的类型工具,它们可以替代传统的递归模板逻辑判断,让代码更简洁易读。这两个类型定义在<type_traits>头文件中,主要作用是对一组类型特性进行逻辑与和逻辑或运算。

std::conjunction的定义与工作原理

std::conjunction的作用是对多个类型特性进行逻辑与运算,只有当所有传入的类型特性都为true时,它的value成员才为true,否则为false。它的实现基于短路求值规则,和运行时逻辑与运算符&&的行为一致。

它的基本定义形式如下:

#include <type_traits>

// 简化版实现示意,实际标准库实现更复杂
template <typename...>
struct conjunction : std::true_type {};

template <typename T>
struct conjunction<T> : T {};

template <typename T, typename... Ts>
struct conjunction<T, Ts...>
    : std::conditional<bool(T::value), conjunction<Ts...>, T>::type {};

从实现可以看出,当第一个类型特性的value为false时,就不会再计算后续的类型特性,直接返回false,这就是短路求值的体现。

std::disjunction的定义与工作原理

std::disjunction的作用是对多个类型特性进行逻辑或运算,只要有一个传入的类型特性为true,它的value成员就为true,只有所有都为false时才为false。它同样支持短路求值,和运行时逻辑或运算符||的行为一致。

简化版实现示意如下:

#include <type_traits>

template <typename...>
struct disjunction : std::false_type {};

template <typename T>
struct disjunction<T> : T {};

template <typename T, typename... Ts>
struct disjunction<T, Ts...>
    : std::conditional<bool(T::value), T, disjunction<Ts...>>::type {};

当第一个类型特性的value为true时,就不会再计算后续的类型特性,直接返回true。

使用场景与代码示例

多类型特性判断

假设我们需要判断一个类型是否同时满足是整型、有符号、不是长整型三个条件,使用std::conjunction可以很简洁地实现:

#include <iostream>
#include <type_traits>
#include <string>

int main() {
    // 判断int是否同时满足三个条件
    bool result1 = std::conjunction<
        std::is_integral<int>,
        std::is_signed<int>,
        std::negation<std::is_same<int, long>>
    >::value;
    std::cout << "int是否符合条件: " << result1 << std::endl; // 输出1

    // 判断long是否满足条件
    bool result2 = std::conjunction<
        std::is_integral<long>,
        std::is_signed<long>,
        std::negation<std::is_same<long, long>> // 这里会为false
    >::value;
    std::cout << "long是否符合条件: " << result2 << std::endl; // 输出0

    return 0;
}

逻辑或判断场景

如果需要判断一个类型是否是整型或者浮点型,使用std::disjunction实现:

#include <iostream>
#include <type_traits>

int main() {
    // 判断int是否是整型或浮点型
    bool result1 = std::disjunction<
        std::is_integral<int>,
        std::is_floating_point<int>
    >::value;
    std::cout << "int是否是整型或浮点型: " << result1 << std::endl; // 输出1

    // 判断std::string是否是整型或浮点型
    bool result2 = std::disjunction<
        std::is_integral<std::string>,
        std::is_floating_point<std::string>
    >::value;
    std::cout << "std::string是否是整型或浮点型: " << result2 << std::endl; // 输出0

    return 0;
}

和传统模板逻辑判断的对比

在C++17之前,要实现多个类型特性的逻辑与判断,通常需要写递归模板,代码冗长且可读性差。例如实现逻辑与判断的传统方式:

#include <type_traits>

// 传统递归模板实现逻辑与
template <typename...>
struct old_conjunction : std::true_type {};

template <typename T>
struct old_conjunction<T> : T {};

template <typename T, typename... Ts>
struct old_conjunction<T, Ts...> {
    static constexpr bool value = T::value && old_conjunction<Ts...>::value;
};

对比可见,std::conjunction是标准库已经实现好的工具,不需要开发者自己重复编写递归模板,减少了出错概率,也让代码更符合标准规范。

注意事项

  • std::conjunction和std::disjunction的模板参数必须是具有value成员的类型,通常是类型特性类。
  • 它们的结果是编译期常量,可以用于模板参数、if constexpr等编译期判断场景。
  • 短路求值特性可以避免不必要的类型计算,比如某个类型特性的计算本身有副作用或者成本较高时,这个特性会很有用。

std::conjunctionstd::disjunctionC++17模板元编程修改时间:2026-06-20 22:15:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。