I need a generic function that can take either a const or non-const reference to a container, and return the corresponding reference to elements qualified as per the container.
Something along these lines:
template <typename C>
auto get_nth( C& c, int i ) -> /* not-sure-what, but let's call it T */
{
//.... some tricky code here ...
}
I would like to stress that if C expands to
SomeContainer const
then T would be
SomeContainer::const_reference
and otherwise
SomeContainer::reference
I think I can put it together using type traits and mtl if, my question is if there is a shorter, cleaner way.
I’m using C++x11 (obviously) and boost.
Thanks in advance.
I think you are looking for
typename C::reference, see 23.2.1 [container.requirements.general] §4.Oh wait, the above doesn’t work if
Cis alreadyconst. But wait,decltypeto the rescue!If you also want to support C-style arrays which have no
beginmember function:And the implementation really isn’t that tricky:
Note that the above solution accepts lvalues and rvalues, but it will always return an lvalue reference. Depending on the client code, this may be a performance concern. Take the following example code:
This will copy the result into
s, even though moving it would be perfectly valid (and, of course, faster).To solve this problem, we need two overloads, one for lvalues and one for rvalues:
Now the result will be moved into
s. Theenable_ifpart is necessary because due to reference collapsing rules,C&&can also bind to lvalues, and then the call to initializeswould be ambiguous.