Decltype and friend functions in Visual Studio vs G++
auto, c++, c++11, decltype, friend
Solution
The definition of class template `MyClass` is not complete by the time you use the expression `std::begin(a.elts)`, so I guess VC has a reason to complain. You cannot use `operator .` on an incomplete type.
In any case, you could work around that by using the following:
#include <iostream>
#include <array>
template <typename T, size_t size>
class MyClass
{
// ...
friend typename std::array<T, size>::iterator begin(MyClass &a)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
return std::begin(a.elts);
}
};
Problem
I was writing some C++ code to do vector math. It is essential just a thin wrapper around a `std::array` instance. I wanted to overload the non-member `begin()` function to return an iterator to the beginning of the backing array. To do this, I wrote a simple friend function with an `auto` return type and a trailing return type using `decltype` that just forwarded the call along to the member variable. It wouldn't compile, and I couldn't figure out why. I started fiddling around with a smaller example and discovered the following code compiles under G++ 4.7, but not under the latest Visual Studio 2012 Professional. ``` #include <iostream> #include <array> template <typename T, size_t size> class MyClass { private: std::array<T, size> elts; public: friend auto begin(MyClass &a) -> decltype (std::begin(a.elts)) { return std::begin(a.elts); } }; int main(void) { MyClass<int, 8> instance; auto it = begin(instance); std::cout << *it << std::endl; return 0; } ``` The odd thing was this code only compiled in G++ if the private declaration of `elts` came before the declaration of the `begin()` function. In any case, which compiler is right here? Visual Studio or G++? Edit: The compile error that VS2012 gave was `error C2228: left of '.elts' must have class/struct/union`