I have operators declared for class my_type
in namespace my_namespace
.
namespace my_namespace {
class my_type
{
friend std::ostream& operator << (std::ostream& out, my_type t);
}
}
I'm trying to define these operators in implementation file, but when I write something like that
std::ostream& my_namespace::operator << (std::ostream& out, my_type t)
{
out << t;
return out;
}
I get error message
error: ... operator should have been declared inside 'my_namespace'
When I change it to
namespace my_namespace {
std::ostream& operator << (std::ostream& out, my_type t)
{
out << t;
return out;
}
}
then it's compiles, but I don't understand the problem. Why does this failed to compile? Is there everything right with that? I would appreciate link to standard as I really don't know what to search.
added
file.h
#ifndef A_H
#define A_H
#include <iosfwd>
namespace N
{
class A
{
friend std::ostream& operator << (std::ostream& out, A& obj);
};
}
#endif
file.cpp
#include "file.h"
#include <iostream>
std::ostream& N::operator << (std::ostream& out, N::A& obj)
{
return out;
}
int main() {}
here is complete example. This works fine on VS2010, but gives above mentioned error on gcc 4.4.5.
added
hmm...yes, this one works
namespace N
{
class A
{
friend std::ostream& operator << (std::ostream& out, A& obj);
};
std::ostream& operator << (std::ostream& out, A& obj);
}
I was always thinking that in terms of visibility declaring friend operator in class is same thing as declaring outside of the class..looks like it's not. Thanks.
Thanks much in advance.
The error message says it all, actually. You can keep your function definition in the implementation file, but you need to declare it in the namespace first:
namespace my_namespace {
std::ostream& operator << (std::ostream& out, my_type t);
}
The C++ standard is quite clear about this:
7.3.1.2/3:
Every name first declared in a namespace is a member of that namespace. If a friend declaration in a non-local class first declares a class or function the friend class or function is a member of the innermost enclosing namespace. The name of the friend is not found by simple name lookup until a matching declaration is provided in that namespace scope (either before or after the class declaration granting friendship). If a friend function is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments (3.4.2). When looking for a prior declaration of a class or a function declared as a friend, and when the name of the friend class or function is neither a qualified name nor a template-id, scopes outside the innermost enclosing namespace scope are not considered. .
The following link puts it more simply, and adds a few examples: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/cplr043.htm
So I'd say that gcc is wrong here.. The relevant sentence seems to be "The name of the friend is not found by simple name lookup until a matching declaration is provided in that namespace scope (either before or after the class declaration granting friendship).
Declarations refer to a set of other names, and introduce a single new name; this new name must not be qualified with a namespace identifier, but rather the declaration needs to be inside the namespace block in which the new name should be declared.
The same rules apply to definitions, as they imply a declaration. The friend declaration is special, because it lives inside another definition and doesn't really declare anything.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With