# std::conjunction

< cpp‎ | types

定义于头文件 `<type_traits>` |  |
template<class... B> struct conjunction; |  | (C++17 起)

组成类型特性 `B...` 的逻辑合取，等效地在特性序列上进行逻辑与。

特化 std::conjunction<B1, ..., BN> 有一个公开且无歧义的基类，即

- 若 sizeof...(B) == 0 ，则是 std::true_type ；否则
- 若 `B1, ..., BN` 中有 bool(Bi::value) == false ，则为首个 `Bi` ，否则若无这种类型，则为 `BN` 。

不隐藏 `conjunction` 及 `operator=` 以外的基类成员名，而它们在 `conjunction` 中无歧义地可用。

合取是短路的：若存在模板类型参数 `Bi` 满足 bool(Bi::value) == false ，则实例化 conjunction<B1, ..., BN>::value 不要求 `j > i` 的 Bj::value 的实例化。

添加 `conjunction` 或 `conjunction_v` 的特化的程序行为未定义。

### 模板形参

B... | - | 每个要实例化 Bi::value 的模板参数 `Bi` 必须可用作基类，且定义了可转换到 bool 的成员 `value`

### 辅助变量模板

template<class... B> inline constexpr bool conjunction_v = conjunction<B...>::value; |  | (C++17 起)

### 可能的实现

    template<class...> struct conjunction : std::true_type { };
    template<class B1> struct conjunction<B1> : B1 { };
    template<class B1, class... Bn>
    struct conjunction<B1, Bn...>
        : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};

### 注解

`conjunction` 的特化不需要继承自 std::true_type 或 std::false_type ：它简单地继承自首个 `B` ，其 `::value` 显式转换为 bool 后为 false ，或在它们都转换为 true 时继承自最后的 `B` 。例如， std::conjunction<std::integral_constant<int, 2>, std::integral_constant<int, 4>>::value 为 4 。

`conjunction` 的短路实例化异于折叠表达式：类似 (... && Bs::value) 的折叠表达式实例化 `Bs` 中的每个 `B` ，而 std::conjunction_v<Bs...> 一旦能确定值就停止实例化。若之后的类型实例化代价高昂，或以错误类型实例化时能导致硬错误，则这特别有用。

### 示例

    #include <iostream>
    #include <type_traits>

    // 若所有 Ts... 都拥有等同于 T 的类型，则启用 func
    template<typename T, typename... Ts>
    std::enable_if_t<std::conjunction_v<std::is_same<T, Ts>...>>
    func(T, Ts...) {
        std::cout << "all types in pack are T\n";
    }

    // 否则
    template<typename T, typename... Ts>
    std::enable_if_t<!std::conjunction_v<std::is_same<T, Ts>...>>
    func(T, Ts...) {
        std::cout << "not all types in pack are T\n";
    }

    int main() {
        func(1, 2, 3);
        func(1, 2, "hello!");
    }

输出：

    all types in pack are T
    not all types in pack are T

### 参阅

negation (C++17) | 逻辑非元函数 (类模板)
disjunction (C++17) | 变参的逻辑或元函数 (类模板)