14
#include <vector>

struct C
{
    std::vector<int> v;
    decltype(v.begin()) begin() { return v.begin(); }
    decltype(v.end()) end() { return v.end(); }
};

Clang++ has no problem, but MSVC 2013 gives the following error:

error C2228: left of '.begin' must have class/struct/union
japreiss
  • 11,111
  • 2
  • 40
  • 77
  • 5
    See http://stackoverflow.com/a/11235245/103167 for why this coding style is broken in any compiler, and you should use trailing-return type for `decltype` on members of `this`. – Ben Voigt Jul 03 '14 at 22:09

1 Answers1

19

This is a known bug in VS2013, fixed in VS2015. The compiler will accept the code if you use a trailing return type instead.

struct C
{
    std::vector<int> v;
    auto begin() -> decltype(v.begin()) { return v.begin(); }
    auto end()   -> decltype(v.end())   { return v.end(); }
};

As the bug report says, another work around is by using:

struct C
{
    std::vector<int> v;
    decltype(std::declval<decltype(v)>().begin()) begin() { return v.begin(); }
    decltype(std::declval<decltype(v)>().end())   end()   { return v.end(); }
};

But as @BenVoigt points out in the comments, read this answer for why the trailing return type should be the preferred option.


Search the linked page for C++ decltype of class-member access incompletely implemented

Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • 2
    What about trailing return type, which the bug report says works fine? `auto begin() -> decltype(v.begin()) { return v.begin(); }` Seems much nicer to me, if it works right – Ben Voigt Jul 03 '14 at 22:07
  • @BenVoigt Agreed, updated the answer. And thanks for linking to that answer by litb, I wasn't aware of that limitation. – Praetorian Jul 03 '14 at 22:44
  • The link is helpfully dead, but it is [mentioned as being fixed in VS2015 here](https://blogs.msdn.microsoft.com/vcblog/2015/07/01/c-compiler-front-end-fixes-in-vs2015/). – Timmmm Apr 15 '18 at 16:22
  • @Timmmm Thanks for the link, I've updated the answer and removed the old link. MS decided to shutdown connect and as usual left no redirect, breaking all those links. – Praetorian Apr 15 '18 at 21:45