代码之家  ›  专栏  ›  技术社区  ›  Generic Name

如何获取参数包中元素的索引

  •  3
  • Generic Name  · 技术社区  · 7 年前

    如何获得以下内容以将参数包元素的索引放入元组中?

    template< typename... Ts >
    class ClassA {
    public:
        ClassA( Ts... ts ) : tup( make_tuple( ts, 0 )... ) {}
        // I would like it to expand to this.
        // ClassA( T0 ts0, T1 ts1 ) : tup( make_tuple( ts0, 0 ), make_tuple(ts1, 1) ) {}
        tuple<tuple<Ts, size_t>...> tup;
    };
    
    void main() {
        vector<int> a ={ 2, 4, 5 };
        list<double> b ={ 1.1, 2.2, 3.3 };
        ClassA<vector<int>, list<double>, vector<int>, list<double>> mm( a, b, a, b );
    }
    

    谢谢

    2 回复  |  直到 7 年前
        1
  •  7
  •   max66    7 年前

    在我看来(如果你至少可以使用C++14),这是一个委托构造函数的工作

    template <typename ... Ts>
    class ClassA
     {
       private:
          template <std::size_t ... Is>
          ClassA (std::index_sequence<Is...> const &, Ts ... ts)
             : tup { std::make_tuple(ts, Is) ... }
           { }
    
       public:
          ClassA (Ts ... ts)
             : ClassA(std::make_index_sequence<sizeof...(Ts)>{}, ts...)
           { }
    
          std::tuple<std::tuple<Ts, std::size_t>...> tup;
     };
    

    在C++11中,这不起作用,因为 std::index_sequence std::make_index_sequence 仅从C++14开始提供,但不难找到(或开发)C++11替代品。

        2
  •  3
  •   Nir Friedman    7 年前

    通过简单地将整数作为包扩展的一部分递增,可以避免将构造函数作为模板和索引序列:

    template <typename ... Ts>
    class ClassA
     {
       private:
          ClassA (size_t i, Ts ... ts)
             : tup { std::make_tuple(ts, i++) ... }
           { }
    
       public:
          ClassA (Ts ... ts)
             : ClassA(0, ts...)
           { }
    
          std::tuple<std::tuple<Ts, size_t>...> tup;
     };
    

    我应该注意到,gcc目前正在警告我缺少一个序列点,但这似乎是一个误报(在任何情况下,编写一个小函数并调用它都可以很容易地解决这个问题)。

    推荐文章