如何以标准方式组合来自type_traits的条件

How to combine conditions from type_traits the standard way

本文关键字:type traits 条件 标准 方式 组合      更新时间:2023-10-16

例如,仅当std::is_pointer<T>std::is_const<T>求值为true_type时,我想使用类型T

当然,还有一种简单的方法:

template <typename T>
void f(T t, std::true_type, std::true_type) {}
template <typename T>
void f(T t)
{
  f(t, std::is_pointer<T>{}, std::is_const<T>{});
}

但是我想要这样的:

template <typename T>
void f(T t, std::true_type) {}
template <typename T>
void f(T t)
{
  f(t, std::and<std::is_pointer<T>, std::is_const<T>>{});
}

标准库包含std::and之类的东西吗?如果没有,是否有一种简单的方法来实现所需的功能?

您可以简单地将性状的结果&&放在一起,并将它们放在std::integral_constant中:

std::integral_constant<bool, 
                       std::is_pointer<T>::value && std::is_const<T>::value>

或者你可以写一个通用特性and。这里有一些可能性:

选项1 :

template<typename... Conds>
  struct and_
  : std::true_type
  { };
template<typename Cond, typename... Conds>
  struct and_<Cond, Conds...>
  : std::conditional<Cond::value, and_<Conds...>, std::false_type>::type
  { };
//usage
and_<std::is_pointer<T>, std::is_const<T>>

选项2 :

template<bool...> struct bool_pack;
template<bool... bs> 
using and_ = std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>;
//usage
and_<std::is_pointer<T>, std::is_const<T>>

当我们得到折叠表达式时,你可以这样做:

template<typename... Args>
using and_ = std::integral_constant<bool, (Args::value && ...) >;

你的编译器可能已经在-std=c++1z标志下支持这个

随着c++ 17连接和析取的出现,您可以轻松地组合可变(数量)谓词:

template <class T, template <class> class... Ps>
constexpr bool satisfies_all_v = std::conjunction<Ps<T>...>::value;
template <class T, template <class> class... Ps>
constexpr bool satisfies_any_v = std::disjunction<Ps<T>...>::value;

你可以这样使用它:

satisfies_all_v<T, is_pointer, is_const>