Daniel Langr
Daniel Langr

Reputation: 23497

Why std::begin uses trailing return type syntax?

The range-access function std::begin is declared as follows (for containers):

template< class C >
auto begin( C& c ) -> decltype(c.begin());

I just wonder why it's not simply

template< class C >
decltype(C::begin) begin( C& c );

Is there any difference between these two?

Upvotes: 3

Views: 109

Answers (2)

Useless
Useless

Reputation: 67723

This version

template< class C >
decltype(C::begin) begin( C& c )

won't work, because

  1. decltype(C::begin) means the type of the method, not the type of the result of the method call, and anyway
  2. the begin method is overloaded for standard containers, and without the context of a function call (even if not evaluated), the compiler will be unable to decide which overload should participate

The std::declval version shown by VTT fixes that, by creating an un-evaluated function call context where the overload can be resolved. Using the trailing decltype instead saves repeating the argument type.

Upvotes: 3

user7860670
user7860670

Reputation: 37513

The equivalent code would be

template< class C >
decltype(::std::declval<C &>().begin()) begin( C& c );

which is longer and potentially more error-prone.

Upvotes: 8

Related Questions