Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
264 views
in Technique[技术] by (71.8m points)

c++ - Type trait to check that all types in a parameter pack are copy constructible

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 check the functionality.

#include <type_traits>
#include <string>
#include <memory> 

template <class... Args0toN>
struct areCopyConstructible;

template<>
struct areCopyConstructible<> : std::true_type {};

template <class Arg0, class... Args1toN, class std::enable_if< !std::is_copy_constructible<Arg0>::value>::type* = nullptr >
struct areCopyConstructible : std::false_type {};

template <class Arg0, class... Args1toN, class std::enable_if< std::is_copy_constructible<Arg0>::value>::type* = nullptr >
struct areCopyConstructible : areCopyConstructible<Args1toN...> {};

int main()
{
  static_assert(areCopyConstructible<>::value, "failed");
  static_assert(areCopyConstructible<int>::value, "failed");
  static_assert(areCopyConstructible<int, std::string>::value, "failed");
  static_assert(!areCopyConstructible<std::unique_ptr<int> >::value, "failed");
  static_assert(!areCopyConstructible<int, std::unique_ptr<int> >::value, "failed");
  static_assert(!areCopyConstructible<std::unique_ptr<int>, int >::value, "failed");
}

Link to Live Example

My idea was to check recursively, whether the head element of the pack is copy-constructible or not and go on further, with the tail. Unfortunately, I do not get this idea to compile. My knowledge about variadic templates is not very advanced. I guess, that enable-if after parameter pack in template list does not work. I have no idea. Does anyone has a good advice, how to solve the problem?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...