Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simulate std::array<15,int &> with tuples [duplicate]

It is clear that std::array<type,count> can't store references. However it is possible to write

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

and get what you expect. See

#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;
}

where a 11 is output. It is however tedious writing it out long hand. How can I generate a type ( in c++11 )

TupleAllSame<type, count>

so that the following are equivalent

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 &>

like image 641
bradgonesurfing Avatar asked Sep 17 '20 09:09

bradgonesurfing


2 Answers

Based on a C++11 implementation of std::index_sequence (that I stuffed into the std14 namespace):

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

like image 193
Quentin Avatar answered Oct 03 '22 06:10

Quentin


std::reference_wrapper can be used as element of array. Syntax will be a little convoluted sometimes, but it works:

#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;
}
like image 41
sklott Avatar answered Oct 03 '22 04:10

sklott