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

创建N个零的索引序列

  •  0
  • Greg von Winckel  · 技术社区  · 6 年前

    我一直想写一本书 zero_sequence 创建 index_sequence 以产生一个新的具有相同数量的值,但都是零。我很困惑为什么会这样:

    template<typename> struct zero_sequence;
    template<size_t...I> 
    struct zero_sequence<index_sequence<I...>> : index_sequence<(I*0u)...>{};
    
    int main( int argc, char *argv[] ) {
    
      using A  = index_sequence<0,1,2,3,4>;
      using B  = make_index_sequence<5>;
      using A0 = zero_sequence<A>;
      using B0 = zero_sequence<B>;
    
      A a;  B b; 
    
      cout <<< std::is_same<A,B>::value << endl; // is false
    
      A0 a0; 
      B0 b0;  // < error implicit instantiation of undefined template
      return 0;
    }
    

    我不明白为什么这两种情况是不同的(在macclangllvm9.0.0上)。

    如果它与解释这种行为有关,我将使用 make_index_sequence 在C++ 11中 I think I got it from here

    template<typename Integer, Integer... I>
    struct integer_sequence {
      using type = integer_sequence;
      using value_type = Integer;
      static constexpr size_t size() noexcept { return sizeof...(I); }
    };
    
    template<size_t... Ints> using index_sequence = integer_sequence<size_t, Ints...>;
    
    template <typename,typename> struct _merge_and_renumber;
    
    template <size_t... I1, size_t... I2>
    struct _merge_and_renumber<index_sequence<I1...>,index_sequence<I2...>> 
      : index_sequence<I1..., (sizeof...(I1)+I2)...> {};
    
    template <size_t N>
    struct make_index_sequence
      : _merge_and_renumber<typename make_index_sequence<N/2>::type,
                            typename make_index_sequence<N - N/2>::type> {};
    
    template<> struct make_index_sequence<0> : index_sequence<> {};
    template<> struct make_index_sequence<1> : index_sequence<0> {};
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   max66    6 年前

    我建议一个 zero_sequence struct 但是 using 基于 decltype() std::declval() 和一个只声明的helper函数(在 例子。

    我是说。。。如果您定义以下助手函数

    template <std::size_t ... Is>
    constexpr auto zeHelper (index_sequence<Is...> const &)
       -> decltype( index_sequence<(Is,0u)...>{} );
    

    零序 可定义为

    template <typename T>
    using zero_sequence = decltype(zeHelper(std::declval<T>()));
    

    两个都可以 a0 b0

    A0 a0; 
    B0 b0; // now works
    

    static_assert( std::is_same<A0, B0>::value, "!" );
    

    我不明白为什么这两种情况不同

    你的问题 零序 模板结构专门化

    template<size_t...I> 
    struct zero_sequence<index_sequence<I...>> : index_sequence<(I*0u)...>{};
    

    template<typename> struct zero_sequence;
    

    所以当你使用 index_sequence 作为模板参数 ,实现的专门化匹配并被选中。

    make_index_sequence ,继承自 索引\u序列 可以转换成 索引\u序列 索引\u序列 ,专用化与的泛型(未实现)版本不匹配 已选中。

    通过一个函数 zeHelper() 我的建议或类似的东西,避免了这个问题,因为 生成索引序列 可转换为 索引\u序列