3

I know that std::get is overloaded. And I know that to extract an overload I need to cast to a specific signature. Let say I need a pointer to std::get which returns non-const ref to 1st element from std::tuple&. Below is one of my many attempts (does not compile):

auto f = static_cast<
    int& (*)(std::tuple<int,int>&) noexcept
>(
    &std::get<(size_t)0u, std::tuple<int,int>>
);

How should I specify this static_cast?

Leonid Volnitsky
  • 8,854
  • 5
  • 38
  • 53

2 Answers2

7

The signature of the tuple get is (directly taken from libstdc++):

 template<std::size_t __i, typename... _Elements>
    constexpr typename __add_ref<     
                      typename tuple_element<__i, tuple<_Elements...>>::type 
                    >::type 
    get(tuple<_Elements...>& __t) noexcept

As such the template parameter to get is the different types of the tuple, not the tuple, so the function you take the address from should be:

&std::get<(size_t)0u,int,int> 
PlasmaHH
  • 15,673
  • 5
  • 44
  • 57
  • I answered a [similar question](http://stackoverflow.com/q/7157210/20984) about a year ago, about `boost::get`. Even though I'm glad to see that `std::tuple` implementation is much simpler thanks to variadic templates, I wish we could have a way of obtaining the types of an `std::tuple` instead of having to repeat them explicitely. With `boost::tuple` we could access them through nested typedefs, but this is not possible with `std::tuple`, we need to rely on an intermediate template to deduce the arguments. If only we could typedef template parameter packs... – Luc Touraille Jul 26 '12 at 13:18
  • @LucTouraille: C++11 does not contain metaprogramming containers and algorithms like boost does, as such it does not have the ability to provide the types. There are however some helper metafunctions to operate on tuple types (tuple_cat, tuple_element, tuple_size), and together with the ability of your own functions that received tuples being able to use variadic templates too, I think the current solution requires about the same amount of effort, just a quite different way of thinking. – PlasmaHH Jul 26 '12 at 13:34
  • Sure, you can always use some indirection to deduce the arguments. For instance, in this case, we could write a generic function for obtaining the correct `get` version without specifying all the parameters, but IMHO, this is a bit more work, even though perhaps a bit cleaner (using an intermediate function makes for more flexibility than accessing nested typedefs, we could create overloads for both `std::` and `boost::` `tuples`, for instance). – Luc Touraille Jul 26 '12 at 13:48
3

Do you need a pointer to an actual std::get or any function with the same behavior will do? If so you can just wrap it in a lambda:

auto f = [](std::tuple<int,int>& tuple) -> int&
{
    return std::get<0>(tuple);
}
yuri kilochek
  • 12,709
  • 2
  • 32
  • 59