led*_*kol 8 c++ gcc namespaces operator-overloading
我my_type在命名空间中为类声明了运算符my_namespace.
namespace my_namespace {
class my_type
{
friend std::ostream& operator << (std::ostream& out, my_type t);
}
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试在实现文件中定义这些运算符,但是当我写这样的东西时
std::ostream& my_namespace::operator << (std::ostream& out, my_type t)
{
out << t;
return out;
}
Run Code Online (Sandbox Code Playgroud)
我收到错误消息
error: ... operator should have been declared inside 'my_namespace'
当我改为
namespace my_namespace {
std::ostream& operator << (std::ostream& out, my_type t)
{
out << t;
return out;
}
}
Run Code Online (Sandbox Code Playgroud)
然后它编译,但我不明白这个问题.为什么这不能编译?那一切都是正确的吗?我很感激链接到标准,因为我真的不知道要搜索什么.
添加
file.h
#ifndef A_H
#define A_H
#include <iosfwd>
namespace N
{
class A
{
friend std::ostream& operator << (std::ostream& out, A& obj);
};
}
#endif
Run Code Online (Sandbox Code Playgroud)
file.cpp
#include "file.h"
#include <iostream>
std::ostream& N::operator << (std::ostream& out, N::A& obj)
{
return out;
}
int main() {}
Run Code Online (Sandbox Code Playgroud)
这是完整的例子.这在VS2010上工作正常,但在gcc 4.4.5上给出了上述错误.
添加
嗯......是的,这个有效
namespace N
{
class A
{
friend std::ostream& operator << (std::ostream& out, A& obj);
};
std::ostream& operator << (std::ostream& out, A& obj);
}
Run Code Online (Sandbox Code Playgroud)
我一直在想,在可见性方面,在课堂上声明朋友操作符与在课堂外声明是一样的.看起来并非如此.谢谢.
非常感谢提前.
Dan*_*ger 10
实际上,错误消息说明了一切.您可以将函数定义保留在实现文件中,但是您需要首先在命名空间中声明它:
namespace my_namespace {
std::ostream& operator << (std::ostream& out, my_type t);
}
Run Code Online (Sandbox Code Playgroud)
C++标准非常明确:
7.3.1.2/3:
首先在名称空间中声明的每个名称都是该名称空间的成员.如果非本地类中的友元声明首先声明一个类或函数,那么友元类或函数是最内层封闭命名空间的成员.直到在该命名空间范围内提供匹配的声明(在授予友谊的类声明之前或之后),才能通过简单的名称查找找到朋友的名称.如果调用了友元函数,则可以通过名称查找找到其名称,该名称查找考虑名称空间中的函数和与函数参数类型相关联的类(3.4.2).当查找声明为朋友的类或函数的先前声明时,并且当友元类或函数的名称既不是限定名称也不是模板标识时,不考虑最内部封闭命名空间范围之外的范围..
下面的链接把它更简单,并增加了几个例子:http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref /cplr043.htm
所以我说gcc在这里是错误的..相关的句子似乎是" 通过简单的名称查找找不到朋友的名字,直到在该命名空间范围内提供匹配的声明(在授予友谊的类声明之前或之后).