user6429576
user6429576

Reputation:

operator<< overload resolution (C++)

The code below gives an error in the a::b::print function: Invalid operands to binary expression ('std::ostream' (aka 'basic_ostream<char>') and 'Foo').

The error goes away if I comment out the operator<< overload in namespace b. But I don't understand why that makes a difference because it has a different signature to the operator<< overload in namspace a. What's going on?!

#include <iostream>

class Foo {};

namespace a {

  std::ostream &operator<<(std::ostream &os, Foo &foo);
  void print(Foo& foo) {
    std::cout << foo;
  }

  namespace b {
    std::ostream &operator<<(std::ostream &os, double d); // uncomment to resolve error
    void print(Foo& foo) {
      std::cout << foo; // error here
    }
  }
}

Upvotes: 1

Views: 46

Answers (1)

Chris Uzdavinis
Chris Uzdavinis

Reputation: 6131

As namespace b is nested inside namespace a, names declared in b will hide names declared in a. When name lookup occurs in a::b::print, it searches b, and if it doesn't find what it's looking for continues searching in a. So it does find operator<< in b and stops looking, and does not even consider the proper one in a. When you comment it out, it doesn't find it in b, and continues searching into a and finds it. You could fix this by adding this in namespace b:

using a::operator<<; 

However, the real problem with your code is that you're not utilizing ADL (argument dependent lookup) properly. Operators that work on user defined types should be in the same namespace as the types they operate on. What ADL does is add extra namespaces to search, so that any arguments (or template parameters) involved with the call will have their namespace considered--automatically. (This is why you can use the operators provided in the std namespace for builtin types when your code is outside std.)

So move operator<< out of namespace a and into the same (global) namespace where Foo is. Or, probably better, move Foo into namespace a.

Upvotes: 1

Related Questions