3

There are some questions which relate to this topic:

How to make a tuple of const references?

std::make_tuple doesn't make references

But neither discusses how to make a tuple of lvalue references from a tuple of values.

Here is what I've got:

template <typename... Args>
std::tuple<Args&...> MakeTupleRef(const std::tuple<Args...>& tuple)
{
    return std::tie(tuple); // this fails because std::tie expects a list of arguments, not a tuple.
}

int main()
{
    std::tuple<int, int> tup;
    std::tuple<int&, int&> tup2 = MakeTupleRef(tup); // the values of tup2 should refer to those in tup
    return 0;
}

As far as I can tell std::tie is ideal here because it produces lvalue references, but it doesn't accept a tuple as an input. How can I get around this problem?

Community
  • 1
  • 1
quant
  • 21,507
  • 32
  • 115
  • 211
  • 1
    Related/duplicate [Initialize tuple of references with reference to tuple](http://stackoverflow.com/q/24918426) – dyp Sep 09 '14 at 22:39
  • `return std::tie( std::get(tuple)... )` would work probably, for an index sequence `Is`. But I wonder if there's a more direct solution. – dyp Sep 09 '14 at 22:40

1 Answers1

2

The usual integer_sequence trick:

template <typename... Args, std::size_t... Is>
std::tuple<Args&...> MakeTupleRef(std::tuple<Args...>& tuple, std::index_sequence<Is...>)
{
    return std::tie(std::get<Is>(tuple)...);
}


template <typename... Args>
std::tuple<Args&...> MakeTupleRef(std::tuple<Args...>& tuple)
{
    return MakeTupleRef(tuple, std::make_index_sequence<sizeof...(Args)>());
}

There's a simpler alternative if the types in the tuple are known to be unique:

template <typename... Args>
std::tuple<Args&...> MakeTupleRef(std::tuple<Args...>& tuple)
{
    return std::tie(std::get<Args>(tuple)...);
}
T.C.
  • 133,968
  • 17
  • 288
  • 421
  • As far as I can tell this will only work on C++14, is that right? – quant Sep 09 '14 at 22:48
  • @Arman C++14, or you can implement `integer_sequence` yourself. There must be half a dozen implementations on SO. – T.C. Sep 09 '14 at 22:49
  • @arman `templatestruct integer_sequence{};templatestruct make_integer_sequence_t:make_integer_sequence_t{};templatestruct make_integer_sequence_t{using type=integer_sequence;};templateusing make_integer_sequence=typename make_integer_sequence_t::type;` should do it. – Yakk - Adam Nevraumont Sep 09 '14 at 23:01