4

I don't understand the reason for this defect report 1207, more specifically in reference to the following sentence (emphasis is mine):

Because the transformation of a member name into a class member access expression (9.3.1 [class.mfct.non-static] paragraph 3) only occurs inside the body of a non-static member function, the type of v in the trailing-return-type is non-const but is const in the return expression, resulting in a type mismatch between the return expression and the return type of the function.

Edit

That is, I don't understand why the type of v in the trailing return type is deduced to be non-const.

Wake up Brazil
  • 3,421
  • 12
  • 19

2 Answers2

9
vector v;
auto end() const -> decltype(v.begin()) { return v.begin(); }

decltype(v.begin()), in the trailing-return-type, is iterator - because v has the type vector, seen from outside.

But inside the functions body, the const-specifier of the member function end() is considered. The type of v is the type of this->v - which in turn depends on the const-ness of this.

this' pointee is const (because of the afore-mentioned const-specifier), thus the type of this inside the member function is block const*.

Therefore the type of this->v inside the member function is vector const (because of the const access-path), and v.begin() - which is actually (this->v).begin() - calls the const-overload whose return type is const_iterator. On the other hand, v.begin() in the trailing-return-type "calls" the non-const overload that returns iterator.

That type inconsistence is the problem.

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • `On the other hand, v.begin() in the trailing-return-type "calls" the non-const overload that returns iterator.` Ok, but why is the non-const overload selected in this case? – Wake up Brazil Sep 09 '14 at 21:59
  • Because the object argument `v` (seen from the trailing-return-type) isn't const-qualified. Therefore overload resolution finds the non-const overload to be a better match. But seen from the traling-return-type, `v` **should** be const-qualified, since the member function is. – Columbo Sep 09 '14 at 22:02
  • What you're saying is that the `const` in the member function declaration doesn't apply to the trailing return type. Could you provide a reference for this? – Wake up Brazil Sep 09 '14 at 22:06
  • @WakeupBrazil Reference is given in the defect report. It says "Because the transformation of a member name into a class member access expression (9.3.1 [class.mfct.non-static] paragraph 3) only occurs inside the body of a non-static member function, the type of v in the trailing-return-type is non-const" – Columbo Sep 09 '14 at 22:10
  • I have no problem with the type inconsistency. What I just don't understand is why the use of `v` in the trailing return type is deduced to be non-const. – Wake up Brazil Sep 09 '14 at 22:15
  • After seeing [this question and the accepted answer](http://stackoverflow.com/q/2844339/1042389) I finally understood what you said above. Thanks. – Wake up Brazil Sep 10 '14 at 18:10
6

It's saying that, when the trailing-return-type is parsed, the member v is looked up to sufficiently make sense of v.begin() .. but the actual access to v in the context of having invoked end() is not considered, so neither is the fact that end() (and therefore its access to v) is const.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055