Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

How do I get a reference to a "get"-function for a specific tuple instance?

My best try is given below but does not compile against g++4.5.1

#include <tuple>
#include <string>
typedef std::tuple<int,std::string> Tuple;
auto t=(std::string& (Tuple&))(std::get<1,Tuple>);

The compiler error is:

a.cc:5: error: invalid cast to function type ‘std::string&(Tuple&)’ 
a.cc:5: error: unable to deduce ‘auto’ from ‘<expression error>’

I would like to use the function reference as an input to some stl-algorithms. I am actually a bit surprised on how non-trivial this seems to be for me.

template <std::size_t I, typename... Types> decltype(&std::get<I, Types...>) get_function(std::tuple<Types...>*) return &std::get<I, Types...>; template <std::size_t I, typename Tuple> decltype(detail::get_function<I>((Tuple*)nullptr)) get_function() return detail::get_function<I>((Tuple*)nullptr); auto t = get_function<I, Tuple>();

Kind of ugly. Surely there's a better way, but that's all I have for now.

I was hoping for a one-liner, but I see how this is supposed to work. gcc-4.5.1 complains about the nullptr, and about type-deduction after that. I will try to adapt this for my compiler later. – mirk Oct 26, 2010 at 7:28 @user Move it into a header, #include "get_function.hpp" is one line. :) What are the errors? – GManNickG Oct 26, 2010 at 7:32 I used "#define nullptr NULL;" as a workaround and got in decltype(detail::get_function<I>((Tuple*)nullptr)) get_function() q.cc:19: error: expected ‘)’ before ‘;’ token q.cc:19: error: expected unqualified-id before ‘)’ token – mirk Oct 26, 2010 at 7:43 @user: Why do you need to define nullptr? It should be defined already. Keep in mind my code is untested, I just wrote it from brain; the error could be in my part and not yours. – GManNickG Oct 26, 2010 at 7:46

After a bit of experimenting, I've found that it is possible using lambda expressions:

#include <tuple>
#include <string>
typedef std::tuple<int, std::string> Tuple;
auto t = [] (Tuple& t) { return std::get<1> (t); };

If you need to use this a lot you could always write a macro:

#define REFERENCE_GET(N, Tuple) \
    [] (Tuple &t) { return std::get<N> (t); }
                I did not consider myself "ready" for lambda's yet, but it looks like there is no way around them in C++0x. The only drawback seems to be that the lambda is not usable as an input to the boost::transform_iterator due to a missing result_type, but that is a different story. Thank you.
– mirk
                Oct 25, 2010 at 18:47

The code below works for me. The trick is to use a function-pointer typedef and not a function reference typedef. I am impressed that the compiler does not need all template parameters, but can optionally work out missing ones through the overloaded function type.

#include <tuple>
#include <string>
typedef std::tuple<int,std::string> Tuple;
typedef std::string& (*PFun)(Tuple&);
PFun p1=(PFun)std::get<1U>;
PFun p2=(PFun)std::get<1U,int,std::string>;

In one line:

auto p3=(std::string& (*)(Tuple&))std::get<1U>;

Sorry to answer my own question. A night sleep can make a big difference.

Ah, if you had been okay with re-specifying the tuples types, it is indeed much shorter. :) Most of the my code is extracting them for you. – GManNickG Oct 26, 2010 at 17:21 Indeed, I did not make it clear that the tuple types are not required. However, the standard provides tuple_element for that. So replacing std::string with std::tuple_element<1,Tuple> in the code above would have handled this as well. – mirk Oct 26, 2010 at 18:13

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.