Namespaces
Variants

std::experimental:: conjunction

From cppreference.net
定义于头文件 <experimental/type_traits>
template < class ... B >
struct conjunction ;
(库基础技术规范 v2)

形成类型特征 B... 逻辑合取 ,实际上是对特征序列执行逻辑与运算。

特化 std :: experimental :: 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 进行实例化。

目录

模板参数

B... - 每个被实例化的模板参数 Bi (其 Bi :: value 需要被实例化)必须可用作基类,并且定义的成员 value 必须可转换为 bool 类型

辅助变量模板

template < class ... B >
constexpr bool conjunction_v = conjunction < B... > :: value ;
(库基础技术规范 v2)

可能的实现

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 :它仅继承自第一个其 ::value 转换为 bool 后为 false 的 B,或者当所有 B 都转换为 true 时继承自最后一个 B。例如, conjunction < std:: integral_constant < int , 2 > , std:: integral_constant < int , 4 >> :: value 的值是 4

示例

#include <experimental/type_traits>
#include <iostream>
// 当所有 Ts... 具有相同类型时启用 func
template<typename T, typename... Ts>
constexpr std::enable_if_t<std::experimental::conjunction_v<std::is_same<T, Ts>...>>
func(T, Ts...)
{
    std::cout << "All types are the same.\n";
}
template<typename T, typename... Ts>
constexpr std::enable_if_t<!std::experimental::conjunction_v<std::is_same<T, Ts>...>>
func(T, Ts...)
{
    std::cout << "Types differ.\n";
}
int main()
{
    func(1, 2'7, 3'1);    
    func(1, 2.7, '3');    
}

输出:

All types are the same.
Types differ.

参见

变参逻辑与元函数
(类模板)