代码之家  ›  专栏  ›  技术社区  ›  Greg von Winckel

如何实现基于序列对操作的C++元函数

  •  1
  • Greg von Winckel  · 技术社区  · 7 年前

    我有一个计算两个索引序列的元素积的实现

    template<size_t...Is,size_t...Js>
    constexpr auto product_sequence_impl( index_sequence<Is...>,
                                          index_sequence<Js...> ) ->
      decltype( index_sequence<(Is*Js)...>() );
    
    template<typename S1, typename S2> using product_sequence = 
    decltype( product_sequence_impl( declval<S1>(), declval<S2>() ) );
    

    这样,当我运行以下代码时

    using A = index_sequence<0,1,2>;
    using B = index_sequence<3,4,5>;
    using C = product_sequence<A,B>;
    
    print_sequence( A{}, cout );
    print_sequence( B{}, cout );
    print_sequence( C{}, cout );
    

    我看到了得到想要的输出

    [ 0 1 2 ]
    [ 3 4 5 ]
    [ 0 4 10 ]
    

    接下来,我尝试创建一个元函数,它可以应用成对结果类2序列:

    template<template<size_t,size_t> class binary_mfun>
    struct binseq_mfun_impl {
    
      template<size_t...Is, size_t...Js>
      constexpr auto method( index_sequence<Is...>,
                             index_sequence<Js...> ) ->
        decltype( index_sequence<binary_mfun<Is,Js>::value...>() );
    
      template<typename S1, typename S2>
      using type = decltype( declval<S1>(), declval<S2>() );
    };
    
    template<template<size_t,size_t> class binary_mfun, typename S1, typename S2>
    using binseq_mfun = typename binseq_mfun_impl<binary_mfun>::template type<S1,S2>;
    

    如果成对产品实现是

    template<size_t I, size_t J> 
    struct binary_product { 
      static constexpr size_t value = I*J; 
    };
    

    但是,当我运行这段代码时

    using D = binseq_mfun<binary_product,A,B>;
    print_sequence( D{}, cout );
    

    我明白了 D 与具有相同的值 B . 看来 binary_mfun 从未使用过。我还尝试使用函数实现此功能 方法,但我不清楚如何处理模板模板 参数

    template<template<size_t,size_t> typename binary_mfun, size_t...Is, size_t...Js>
    constexpr auto binseq_mfun_impl( binary_mfun /*<?,?>*/,
                                     index_sequence<Is...>,
                                     index_sequence<Js...> ) ->
      index_sequence<binary_mfun<Is,Js>::value...>;
    
    template<typename binary_mfun, typename S1, typename S2>
    using binseq_mfun = 
    decltype(binseq_mfun_impl( declval<binary_mfun>(), 
                               declval<S1>(), 
                               declval<S2>() ) );
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Greg von Winckel    7 年前

    感谢昆廷和巴里的评论,同时也意识到 method 需要 static 以下是完整的工作版本:

    // Metafunction for binary operations on sequences
    template<template<size_t,size_t> class binary_mfun>
    struct binseq_mfun_impl {
    
      template<size_t...Is, size_t...Js>
      static constexpr auto method( index_sequence<Is...>,
                                    index_sequence<Js...> ) ->
          index_sequence<binary_mfun<Is,Js>::value...>;
    
      template<typename S1, typename S2>
      using type = decltype( method( declval<S1>(), declval<S2>() ) );
    };
    
    template<template<size_t,size_t> class binary_mfun, typename S1, typename S2>
    using binseq_mfun = typename binseq_mfun_impl<binary_mfun>::template type<S1,S2>;   
    
    // Example binary function
    template<size_t I, size_t J> 
    struct binary_product { static constexpr size_t value = I*J; };
    
    // Example usage
    using A = index_sequence<0,1,2>;
    using B = index_sequence<3,4,5>;
    using C = binseq_mfun<binary_product,A,B>;   // Has values 0,4,10
    
    推荐文章