Search code examples
c++functionclassnamespacesfriend

Unexpected error about no return type in friend declaration in C++


I am trying to compile the following code (simplified from actual use) using g++:

namespace A {
    class B;
}

A::B operator+(A::B a, A::B b);

namespace A {
    class B {
    private:
        int i;
    public:
        B() : i(0) {}
        B(int j) : i(j) {}

        friend B ::operator+(B a, B b);
    };
}

A::B operator+(A::B a, A::B b) {
    return A::B(a.i + b.i);
}

int main() {
    A::B a(1), b(2);
    A::B c = a+b;
    return 0;
}

To the best of my understanding, the friend declaration in class B is correct, and the :: global scope declaration is needed otherwise the compiler assumes that A::operator+(B a, B b) is meant.

However, on compiling this, gcc gives the error message

ISO C++ forbids declaration of ‘operator+’ with no type

I have no idea how to fix this. The error messages after it give the impression that gcc is ignoring the space between B and :: in that line, instead interpreting this as a friend declaration of a member function of B. How can I tell it what I want?


Solution

  • Declare the friend operator inside the class definition the following way

    friend B (::operator+) (B a, B b);
    

    or like

    friend B (::operator+(B a, B b));
    

    Otherwise the compiler considers it like a member function of the class declared without an explicit return type (int is implied)

    friend B::operator+(B a, B b);
    

    Though it would be much better to declare it like

    friend B (::operator +)( const B &a, const B &b);