代码之家  ›  专栏  ›  技术社区  ›  Mathieu Van Nevel

C++概念循环

  •  2
  • Mathieu Van Nevel  · 技术社区  · 8 年前

    我想让编译器检查元组是否只包含“元类型”。

    顺便说一句,我对C++的概念完全陌生。

    template < typename T >
    struct Type {
      using type = T;
    };
    
    //! A type can be easily check with a small concept
    template < typename T >
    concept bool  C_Type = requires {
      typename T::type;
    };
    
    //! But how to apply it on a whole tuple?
    template < typename T >
    void foo(T tuple) {}
    
    int main() {
    
      constexpr auto  test = std::make_tuple(Type<int>{}, Type<double>{});
      foo(test);
    }
    

    如果Boost Hana可以简化代码,我正在使用它。

    目前我甚至不确定这是否可能。我希望是这样,我想我只需要学习更多的元编程的东西。所以我会继续搜索和尝试,但如果有人已经有了答案,谢谢!

    3 回复  |  直到 8 年前
        1
  •  3
  •   Casey    8 年前

    概念在设计上太弱,无法执行元编程,因此要做到这一点,您需要该语言其余部分的一些“元编程帮助”。我将使用模板专门化将类型分解为模板及其类型参数,然后要求所有这些参数满足 C_Type

    template <class>
    constexpr bool TypeTuple_ = false;
    template <template <class...> class Tuple, class... Types>
      requires (C_Type<Types> && ...)
    constexpr bool TypeTuple_<Tuple<Types...>> = true;
    
    template <class T>
    concept bool TypeTuple = TypeTuple_<T>;
    

    hana::tuple std::tuple -接受所有类型参数的任何模板。

        2
  •  2
  •   Jason Rice    8 年前

    我对概念不太熟悉,但使用Boost肯定可以实现这一点。Hana在许多方面都是如此。

    hana::Sequence 根据惯例 hana::Searchable hana::Foldable

    std::tuple 用作 hana::可搜索

    #include <boost/hana.hpp>
    #include <boost/hana/ext/std/tuple.hpp>
    #include <tuple>
    namespace hana = boost::hana;
    
    template < typename T >
    concept bool  C_Type = requires {
      typename T::type;
    };
    
    auto is_C_Type = hana::overload_linearly([](C_Type const&) { return hana::true_c; },
                                             [](auto const&)   { return hana::false_c; });
    
    template < typename T >
    constexpr bool foo(T const& tuple) {
      return hana::all_of(tuple, is_C_Type);
    }
    
    int main() {
      constexpr auto  test = std::tuple{hana::type_c<int>, hana::type_c<double>};
      static_assert(foo(test));
    }
    

    https://wandbox.org/permlink/YNZDX7uN6mgUdmje

        3
  •  1
  •   BeyelerStudios    8 年前

    下面是一个示例,说明如何检查 tuple 仅包含定义typename的类型 type . 这里的技巧是定义一个元组类型来定义一个新类型 std::pair<std::pair<...std::pair<void, T0>, ...TN>, TM> 对于元组 std::tuple<T0, ..., TN, TM> . 这 works in GCC 7.2

    #include <array>
    #include <tuple>
    
    template<typename T>
    struct Type {
        using type = T;
    };
    
    template<typename Tuple, size_t I = std::tuple_size<Tuple>::value>
    struct TupleType {
        using type = std::pair<typename TupleType<Tuple, I - 1>::type,
                               typename std::tuple_element<I - 1, Tuple>::type>;
    };
    
    template<typename Tuple>
    struct TupleType<Tuple, 0> {
        using type = void;
    };
    
    template<typename T>
    concept bool C_TupleType = requires {
        typename TupleType<T>::type;
    };
    
    void foo(C_TupleType tuple) { }
    
    int main() {
        constexpr auto test = std::make_tuple(Type<int>{}, Type<double>{});
        foo(test);
    
        // also works on pair and array
        constexpr auto test1 = std::make_pair(Type<int>{}, Type<double>{});
        foo(test1);
        constexpr std::array<Type<int>, 3> test2;
        foo(test2);
    
        // and of course TupleType is also a meta type
        constexpr std::array<TupleType<std::pair<int, int>>, 13> test3;
        foo(test3);
    
        return 0;
    }
    
    推荐文章