Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decltype and friend functions in Visual Studio vs G++

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

like image 567
David Adrian Avatar asked Mar 13 '13 00:03

David Adrian


1 Answers

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);
    }
};
like image 162
Andy Prowl Avatar answered Nov 09 '22 00:11

Andy Prowl