1

I have a function that takes a tuple and I want to iterate over the tuple members in order. My current version is compiler dependent because it uses function parameters to unpack the tuple members (in std::make_tuple()).

I have build a simplified example of what I am doing:

template<typename T>
void* printMember(T const& d)
{
    std::cout << d << " ";
    return nullptr;
}
template<typename Members, std::size_t... Seq>
void printTuppleMembers(Members const& members, std::index_sequence<Seq...> const&)
{
    std::make_tuple(printMember(std::get<Seq>(member))...);
}
template<typename... Members>
void printTupple(std::tuple<Members...> const& members)
{
    printTuppleMembers(members, std::make_index_sequence<sizeof...(Members)>());
}

I can not think of a way to force the calling of printMember() for each member of the tupple so that it happens for the members 0..n in the correct order.

I tried using initializer lists.

std::make_tuple({printMember(std::get<Seq>(member))...});
         //     ^                                     ^

But this did not compile.

It currently works on my system but I would like a generic solution that works on all systems.

Martin York
  • 257,169
  • 86
  • 333
  • 562

1 Answers1

2

A pack expansion inside a braced initializer list is guaranteed left-to-right evaluation:

auto discard = {0, (printMember(std::get<Seq>(members)), 0)...};
(void)discard;
David G
  • 94,763
  • 41
  • 167
  • 253
  • You are missing a `void` cast, or a `void()`, just in case `printMember` returns an evil type with an overloaded `operator,`: as `printMember` is looked up in an ADL enabled context, any member type could have a local overload, and you'd get strange side effects. It seems prudent to avoid that. – Yakk - Adam Nevraumont Apr 14 '15 at 14:31