std::tuple get() member function
Asked Answered
B

3

58

boost::tuple has a get() member function used like this:

tuple<int, string, string> t(5, "foo", "bar");
cout << t.get<1>();  // outputs "foo"

It seems the C++0x std::tuple does not have this member function, and you have to instead use the non-member function form:

std::get<1>(t);

which to me looks uglier.

Is there any particular reason why std::tuple doesn't have the member function? Or is it just my implementation (GCC 4.4)?

Bonaire answered 22/7, 2010 at 21:6 Comment(1)
As a design rule of thumb, non-member functions are to be preferred anyway.Wheaton
A
72

From C++0x draft:

[ Note: The reason get is a nonmember function is that if this functionality had been provided as a member function, code where the type depended on a template parameter would have required using the template keyword. — end note ]

This can be illustrated with this code:

template <typename T>
struct test
{
  T value;
  template <int ignored>
  T&  member_get ()
  {  return value;  }
};

template <int ignored, typename T>
T&  free_get (test <T>& x)
{  return x.value;  }

template <typename T>
void
bar ()
{
  test <T>  x;
  x.template member_get <0> ();  // template is required here
  free_get <0> (x);
};
Actuary answered 22/7, 2010 at 21:26 Comment(3)
I see. Still, they could have provided both member and non-member functions like boost, if for no other reason that to be compatible with boost (since a lot of people are likely to have already been using boost tuples before switching to C++0x).Bonaire
@Bonaire Whereas I understand your argument, boost compatibility alone is not a sufficient reason on its own, since compatibility to existing solutions shouldn't be the only driving force for providing something in a new standard and even boost is not the non-plus-ultra and may profit from some revision. Those general words being said, I still agree that member-gets would have been a good idea.Arad
Now that we have C++11 that no longer requiring template keyword, we can totally have a member function now? Just a proposal needed?Averment
W
34

The existing answers are great and certainly for the standards committee were vital for this purpose. But there is another issue that I think is important enough to mention.

With free functions, you have the ability to modify an interface without changing the definition of a class. You can make any type "gettable" simply by specializing the global get. With a member function, you would have to directly modify the class.

Range-based for looks for member begin/end on class types, but it also looks for non-member begin/end via ADL. These APIs can be used with any container, even those that don't have begin/end functions. You can specialize it for, for example, LibXML2 element types, such that you can range-based for over xmlElement*'s.

You can't do that if they had to be member functions.

In C++, free functions are a natural interface for many operations that could be done on many different kinds of classes.

Watery answered 16/10, 2012 at 3:37 Comment(2)
std::begin/std::end are also good examples of how member and non-member functions can work together nicely. You can use either with most containers.Evolutionary
Ok this is cool and all but provide the member function too!!Lohrman
P
15

N3090/3092, §20.4.2.6/8: "Note: The reason get is a nonmember function is that if this functionality had been provided as a member function, code where the type depended on a template parameter would have required using the template keyword. —end note"

Pneumatometer answered 22/7, 2010 at 21:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.