I need a type trait to check whether all types in a parameter pack are copy constructible. This is what I\'ve done so far. The main function contains some test cases, to che
First define a reusable utility to test whether every predicate in a pack is true:
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
{ };
Then it's trivial to use that with is_copy_constructible
(or any other unary type trait):
template<typename... T>
using areCopyConstructible = and_<std::is_copy_constructible<T>...>;
One advantage of defining and_
like this is that it short-circuits, i.e. stops instantiating is_copy_constructible
for the rest of the pack after the first false result.
If the inheritance from std::true_type
or std::false_type
is not important, then this can be done in straightforward way without SFINAE:
template <class... Args0toN>
struct areCopyConstructible;
template<>
struct areCopyConstructible<> : std::true_type {};
template <class Arg0, class... Args1toN>
struct areCopyConstructible<Arg0, Args1toN...> {
static constexpr bool value = std::is_copy_constructible<Arg0>::value
&& areCopyConstructible<Args1toN...>::value;
};
If you want to inherit from std::true_type
or std::false_type
, you can use std::conditional
:
template <class... Args0toN>
struct areCopyConstructible;
template<>
struct areCopyConstructible<> : std::true_type {};
template <class Arg0, class... Args1toN>
struct areCopyConstructible<Arg0, Args1toN...> :
std::conditional<std::is_copy_constructible<Arg0>::value,
areCopyConstructible<Args1toN...>,
std::false_type
>::type
{};
I know that it is an old question but as we will have C++17 soon, I encourage to take a look at std::conjunction. With it you could write something like this
template <typename ...Args>
using areCopyConstructible = typename std::conjunction<std::is_copy_constructible<Args>...>::type;
I prefer @Columbo's bool_pack
trick. First a template to test that everything in a bool
parameter pack is true
:
template<bool...> struct bool_pack;
template<bool... bs>
using all_true = std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>;
Then
template<class... Ts>
using areCopyConstructible = all_true<std::is_copy_constructible<Ts>::value...>;