c ++如何从type_traits标准方式组合条件

use*_*932 11 c++ templates type-traits c++11

例如,我想T只在它是std::is_pointer<T>和时使用类型std::is_const<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>{});
}
Run Code Online (Sandbox Code Playgroud)

但是我想要这样的东西:

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>>{});
}
Run Code Online (Sandbox Code Playgroud)

在c ++标准类中是什么样的true_type?如果不是,是否有任何简单的方法来实现它,具有所需的功能?

Tar*_*ama 15

您可以简单地&&将特征的结果放在一起并将它们放在std::integral_constant:

std::integral_constant<bool, 
                       std::is_pointer<T>::value && std::is_const<T>::value>
Run Code Online (Sandbox Code Playgroud)

或者你可以写一个通用的特征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>>
Run Code Online (Sandbox Code Playgroud)

选项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>>
Run Code Online (Sandbox Code Playgroud)

当我们得到折叠表达式时,你将能够做到这一点:

template<typename... Args>
using and_ = std::integral_constant<bool, (Args::value && ...) >;
Run Code Online (Sandbox Code Playgroud)

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


Nik*_*iou 7

随着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;
Run Code Online (Sandbox Code Playgroud)

这就是你如何使用它:

satisfies_all_v<T, is_pointer, is_const>
Run Code Online (Sandbox Code Playgroud)

演示