Error with friend declarations and namespaces

Matt Fago fago@earthlink.net
Fri Sep 18 21:44:00 GMT 2009


This following bit of (reduced) code compiles fine on icc 11.1 and VS2005, but is rejected (via a simple 'gcc -o C.o -c C.cpp') by gcc 4.3.0 [g++ (GCC) 4.3.0 20080428 (Red Hat 4.3.0-8)] with the error:

     error: ‘std::ostream& A::B::operator<<(std::ostream&, A::B::C&)’ should have been declared inside ‘A::B’

It seemingly is related to friend injection (-ffriend-injection eliminates the message).

C.h:
---
#include <iostream>
namespace A {
  namespace B {
    class C {
    public:
      friend std::ostream & operator<< ( std::ostream &os, C &in );
    };
  }
}
---
C.cpp:
---
#include "C.h"
using namespace A::B;
std::ostream & A::B::operator<< ( std::ostream &os, C &in ){return os;}
---


Removing the A::B from the definition of << fixes the issue, but adding A::B to the friend declaration inside C does not. So is it a simple declaration mismatch issue? Declaring the operator in namespace A::B, as suggested by the error message, also works. However, why is that declaration necessary? Shouldn't ADL find it anyhow? 

This was really confounding because in most of our code 'C' is a derived class, with the parent also a friend to another << operator. Thus the following works somehow (with the same cpp file):

C.h
---
#include <iostream>
namespace A {
  namespace B {
    class D {
    public:
      friend std::ostream & operator<< ( std::ostream &os, D &in );
    };
    class C : public D {
    public:
      friend std::ostream & operator<< ( std::ostream &os, C &in );
    };
  }
}
---

Perhaps the latter success is a limitation of the error checking.

Any insight into the real issue here?


Thanks,
Matt




More information about the Gcc-help mailing list