Reputation: 8142
For example, I want to use type T
only if std::is_pointer<T>
and std::is_const<T>
evaluate to true_type
.
Of course, there is a simple way like this:
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>{});
}
But I want something like this:
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>>{});
}
Does the Standard Library contain something like std::and
? If not, is there a simple way to implement it with the desired functionality?
Upvotes: 12
Views: 3471
Reputation: 31549
With the advent of C++17 conjunction and disjunction you could easily compose for variadic (number of) predicates:
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;
And this is how you'd use it:
satisfies_all_v<T, is_pointer, is_const>
Upvotes: 8
Reputation: 65710
You can simply &&
together the results of the traits and put them in a std::integral_constant
:
std::integral_constant<bool,
std::is_pointer<T>::value && std::is_const<T>::value>
Or you can write a generic trait and
. Some possibilities from here:
Option 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>>
Option 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>>
When we get fold expressions you'll be able to do this:
template<typename... Args>
using and_ = std::integral_constant<bool, (Args::value && ...) >;
Your compiler may already support this under the -std=c++1z
flag like this.
Upvotes: 16