C++ 如何在另一个C++;名称空间?
我想在全局名称空间中定义一个二进制运算符。接线员 用于在另一个命名空间中定义的类,并且运算符应 访问该类的私有成员。我的问题是我没有 知道如何在类定义中将该全局运算符作为朋友时确定其范围 我试过这样的方法:C++ 如何在另一个C++;名称空间?,c++,namespaces,scope,friend,C++,Namespaces,Scope,Friend,我想在全局名称空间中定义一个二进制运算符。接线员 用于在另一个命名空间中定义的类,并且运算符应 访问该类的私有成员。我的问题是我没有 知道如何在类定义中将该全局运算符作为朋友时确定其范围 我试过这样的方法: namespace NAME { class A { public: friend A ::operator * (double lhs, const A& rhs); private: int
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)
如果在操作符的声明中省略::,编译工作正常,但操作符位于名称空间名称中,而不在全局名称空间中
在这种情况下,如何限定全局名称空间?我不知道您问题的确切答案
但是,在其参数的名称空间之外定义运算符是一个糟糕的主意(现在,您可以剪切对运算符非常有用的依赖于参数的查找)。这是编译的,我假设它也可以工作,而不需要测试。注意括号的使用:
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提到的,您的问题并没有解释为什么操作符不在名称空间名称中。无论哪种方式,它都可以称为
1.0*某个\u A\u实例
。因此,您可能给自己制造了不必要的麻烦。这是可能的-您可以将声明符括在括号中:友元A(::运算符*(双lhs,常数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的观点,如果可能的话,最好在同一名称空间中定义这两个名称空间。首先,请注意,您的运算符声明缺少以下名称空间限定:
NAME::A operator * (double lhs, const NAME::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是对的——您可能应该在与其参数相同的名称空间中声明运算符。Darn,您比我快了大约20秒。代码也差不多。太好了,你救了我一天。我不知道接线员可以名存实亡,但仍然按照我想要的方式工作。这是三个几乎相同的答案:-)当然,你的意思是只有三个:)+1。虽然这个答案直指问题的根源,但有一点需要吹毛求疵:如果op*在全局范围内,那么您不需要ADL,因为该函数总是可用的。(我不确定,但也许OP不了解ADL,因此想出了这个?)
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;
}