【问题标题】:How to simulate std::array<15,int &> with tuples [duplicate]如何使用元组模拟 std::array<15,int &> [重复]
【发布时间】:2020-09-17 09:15:59
【问题描述】:

很明显std::array&lt;type,count&gt; 不能存储引用。但是可以写

std::tuple<int &, int &, int &, int &, int &>

得到你所期望的。见

#include <array>
#include <tuple>
#include <iostream>

int main(){
    int a = 10;
    int b = 20;
    int c = 20;

    // Does not compile
    //std::array<int&,3> x = {a,b,c};

    using TInt3 = std::tuple<int&,int&,int&>;
    TInt3 y = {a,b,c};

    std::cout << sizeof(TInt3) << std::endl;
    std::get<0>(y)=11;
    std::cout << "a " << a << std::endl;
}

a 11 在哪里输出。然而,长手写出来是很乏味的。如何生成类型(在 c++11 中)

TupleAllSame&lt;type, count&gt;

所以下面是等价的

TupleAllSame<int &, 2>   <--> std::tuple<int &, int &>
TupleAllSame<double, 4>  <--> std::tuple<double, double, double, double>
TupleAllSame<std::string &, 3>  <--> std::tuple<std::string &, std::string &, std::string &>

【问题讨论】:

    标签: c++ c++11 tuples template-meta-programming


    【解决方案1】:

    std::reference_wrapper 可以用作数组的元素。语法有时会有点复杂,但它确实有效:

    #include <functional>
    #include <array>
    #include <iostream>
    
    int main(){
        int a = 10;
        int b = 20;
        int c = 20;
    
        using rint = std::reference_wrapper<int>;
        std::array<rint,3> x = {a,b,c};
    
        std::cout << "a " << a << std::endl;
        x[0].get()=11;
        std::cout << "a " << a << std::endl;
    }
    

    【讨论】:

      【解决方案2】:

      基于C++11 implementation of std::index_sequence(我填充到std14 命名空间):

      namespace impl {
          template <class T, class Idx>
          struct TupleAllSame;
          
          template <class T, std::size_t... Idx>
          struct TupleAllSame<T, std14::index_sequence<Idx...>> {
              template <class U, std::size_t>
              using depend = U;
          
              using type = std::tuple<depend<T, Idx>...>;
          };
      }
      
      template <class T, std::size_t Size>
      using TupleAllSame = typename impl::TupleAllSame<T, typename std14::make_index_sequence<Size>::type>::type;
      

      See it live on Wandbox

      【讨论】:

      • @Scheff 澄清 :)
      【解决方案3】:

      基于递归Wandbox Live)的无index_sequence解决方案

      #include<iostream>
      #include <tuple>
      using namespace std;
      
      template <int N, typename T, typename SeqWithArgs>
      struct append;
      
      template <int N, typename T, template <typename...> class Seq, typename... Args >
      struct append<N, T, Seq<Args...> >
      {
          using type = typename append<N - 1, T, Seq<T, Args...> >::type;
      };
      
      template <typename T, template<typename...> class Seq, typename... Args>
      struct append<0, T, Seq<Args...> >
      {
          using type = Seq<Args...>;
      };
      
      template <typename T, size_t Size>
      using TupleAllSame = typename append<Size, T, std::tuple<> >::type;
      
      int main()
      {
          int a = 0, b = 1, c = 2;
          TupleAllSame<int&, 3> t = { a,b, c };
      
          get<0>(t) = 10;
          cout << "a = " << a << endl;
      
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 2018-08-28
        • 2020-04-05
        • 1970-01-01
        • 2013-07-19
        • 1970-01-01
        • 2013-08-20
        • 1970-01-01
        • 2011-12-07
        • 1970-01-01
        相关资源
        最近更新 更多