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

后端 未结 4 483
生来不讨喜
生来不讨喜 2020-12-08 04:36

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

相关标签:
4条回答
  • 2020-12-08 05:07

    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.

    0 讨论(0)
  • 2020-12-08 05:18

    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
    {};
    
    0 讨论(0)
  • 2020-12-08 05:27

    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;
    
    0 讨论(0)
  • 2020-12-08 05:31

    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...>;
    
    0 讨论(0)
提交回复
热议问题