Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在另一个C++;名称空间?_C++_Namespaces_Scope_Friend - Fatal编程技术网

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;
}