如何以标准方式组合 type_traits 中的条件
How to combine conditions from type_traits the standard way
例如,我只想在 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>>
当我们得到 fold expressions 时,您将能够执行此操作:
template<typename... Args>
using and_ = std::integral_constant<bool, (Args::value && ...) >;
您的编译器可能已经在 -std=c++1z
标志下支持此功能,例如 this。
随着 C++17 conjunction and disjunction 的出现,您可以轻松地编写可变参数(数量)谓词:
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>
例如,我只想在 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>>
当我们得到 fold expressions 时,您将能够执行此操作:
template<typename... Args>
using and_ = std::integral_constant<bool, (Args::value && ...) >;
您的编译器可能已经在 -std=c++1z
标志下支持此功能,例如 this。
随着 C++17 conjunction and disjunction 的出现,您可以轻松地编写可变参数(数量)谓词:
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>