如何在另一个 C++ 命名空间内的全局命名空间中定义朋友?
Posted
技术标签:
【中文标题】如何在另一个 C++ 命名空间内的全局命名空间中定义朋友?【英文标题】:How do I define friends in global namespace within another C++ namespace? 【发布时间】:2011-01-13 12:20:25 【问题描述】:我想在全局命名空间中定义一个二元运算符。运营商 适用于在另一个命名空间中定义的类,操作员应该得到 访问该类的私有成员。我的问题是我没有 知道如何在类定义中使全局运算符成为朋友时对其进行作用域。
我尝试了类似的方法:
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;
...
编译器 (g++ 4.4) 不知道如何处理它。好像这条线
friend A ::operator * ()
被评估为类似(伪代码)
(A::operator)
而不是
(A) (::operator)
如果我在运算符的声明中省略 :: 编译工作,但运算符在命名空间 NAME 中,而不是在全局命名空间中。
在这种情况下如何限定全局命名空间?
【问题讨论】:
【参考方案1】:首先,请注意您的运算符声明缺少 A 的命名空间限定:
NAME::A operator * (double lhs, const NAME::A& rhs)
然后决定性的技巧是像这样在朋友声明中添加括号,就像您在“伪代码”中提出的那样
friend A (::operator *) (double lhs, const A& rhs);
为了让它全部编译,你需要一些前向声明,到达这个:
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 是对的——您可能应该在与其参数相同的命名空间中声明运算符。
【讨论】:
现在有 3 个几乎相同的答案 :-) 当然,你的意思是只有三个:)【参考方案2】:这是可能的 - 您可以将声明符括在括号中:friend A (::operator * (double lhs, const A& rhs));
您还需要前向声明类和函数。
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)
//...
但我同意 Andreas 的观点,如果可能,最好将两者定义在同一个命名空间中。
【讨论】:
【参考方案3】:这个编译,我假设没有测试它也可以工作。注意括号的使用:
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;
return rhs;
int main()
不过,正如 Alexander 所提到的,您的问题并没有解释为什么运算符不在命名空间 NAME 中。无论哪种方式,它都可以称为1.0 * some_A_instance
。所以你可能会给自己制造不必要的麻烦。
【讨论】:
该死,你比我早了大约 20 秒。代码也几乎相同。 太好了,你拯救了我的一天。我不知道操作员可以驻留在 NAME 中并且仍然按照我想要的方式工作。【参考方案4】:我不知道你的问题的确切答案。
但是在其参数的命名空间之外定义运算符是一个非常糟糕的主意(现在你削减了对运算符非常有用的参数依赖查找)。
【讨论】:
+1。虽然这个答案切入了问题的根源,但有一点点挑剔:如果 op* 在全局范围内,那么您不需要 ADL,因为该功能始终可用。 (我不确定,但也许 OP 不了解 ADL,因此想出了这个?)以上是关于如何在另一个 C++ 命名空间内的全局命名空间中定义朋友?的主要内容,如果未能解决你的问题,请参考以下文章