How do I define friends in global namespace within another C++ namespace?

Andreas picture Andreas · Feb 5, 2010 · Viewed 7.5k times · Source

I'd like to define a binary operator on in the global namespace. The operator works on a class that is defined in another namespace and the operator should get access to the private members of that class. The problem I have is that I don't know how to scope that global operator when making it a friend in the class definition.

I tried something like:

namespace NAME
{
    class A {
        public:
            friend A ::operator * (double lhs, const A& rhs);
        private:
            int private_var;
    };
}

A operator * (double lhs, const A& rhs)
{
    double x = rhs.private_var;
    ...
}

The compiler (g++ 4.4) didn't know what to do with it. It seems that the line

friend A ::operator * ()

is evaluated as something like (pseudo-code)

(A::operator)

instead of

(A) (::operator)

If I leave out the :: in the declaration of the operator the compiling works but the operator is then in namespace NAME and not in the global namespace.

How can I qualify the global namespace in such a situation?

Answer

Martin B picture Martin B · Feb 5, 2010

First, note that your operator declaration was lacking a namespace qualification for A:

NAME::A operator * (double lhs, const NAME::A& rhs)

and then the decisive trick is to add parentheses to the friend declaration like this, just as you proposed in your "pseudo-code"

friend A (::operator *) (double lhs, const A& rhs);

To make it all compile, you then need some forward declarations, arriving at this:

namespace NAME
{
    class A;
}

NAME::A operator * (double lhs, const NAME::A& rhs);

namespace NAME
{
    class A {
        public:
            friend A (::operator *) (double lhs, const A& rhs);
        private:
            int private_var;
    };
}

NAME::A operator * (double lhs, const NAME::A& rhs)
{
    double x = rhs.private_var;
}

Alexander is right, though -- you should probably declare the operator in the same namespace as its parameters.