如何在另一个 C++ 中的全局命名空间中定义朋友命名空间?

发布于 2024-08-20 18:08:36 字数 696 浏览 5 评论 0原文

我想在全局命名空间中定义一个二元运算符。操作员 适用于在另一个名称空间中定义的类,并且运算符应该得到 访问该类的私有成员。我的问题是我不 知道在类定义中使其成为友元时如何确定全局运算符的范围。

我尝试过类似的操作:

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 中,而不是在全局命名空间中。

在这种情况下如何限定全局命名空间?

I'd like to define a binary operator on in the global namespace. The operator
works on a class that is defined in another namespace and the operator should get
access to the private members of that class. The problem I have is that I don't
know how to scope that global operator when making it a friend in the class definition.

I tried something like:

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

The compiler (g++ 4.4) didn't know what to do with it. It seems that the line

friend A ::operator * ()

is evaluated as something like (pseudo-code)

(A::operator)

instead of

(A) (::operator)

If I leave out the :: in the declaration of the operator the compiling works but the operator is then in namespace NAME and not in the global namespace.

How can I qualify the global namespace in such a situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

揽月 2024-08-27 18:08:36

首先,请注意您的运算符声明缺少 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;
}

亚历山大是对的,不过——您可能应该在与其参数相同的命名空间中声明该运算符。

First, note that your operator declaration was lacking a namespace qualification for A:

NAME::A operator * (double lhs, const NAME::A& rhs)

and then the decisive trick is to add parentheses to the friend declaration like this, just as you proposed in your "pseudo-code"

friend A (::operator *) (double lhs, const A& rhs);

To make it all compile, you then need some forward declarations, arriving at this:

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 is right, though -- you should probably declare the operator in the same namespace as its parameters.

北渚 2024-08-27 18:08:36

这可以编译,我假设没有测试它也可以工作。请注意括号的使用:

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。所以你可能会给自己制造不必要的麻烦。

This compiles, I assume without testing that it also works. Note the use of parentheses:

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() {}

As Alexander mentions, though, your question doesn't explain why the operator isn't in namespace NAME. Either way it can be called as 1.0 * some_A_instance. So you may be creating needless trouble for yourself.

骄兵必败 2024-08-27 18:08:36

我不知道你的问题的确切答案。

但是在其参数的名称空间之外定义运算符是一个非常糟糕的主意(现在您可以删除对运算符非常有用的参数依赖查找)。

I don't know exact answer to your question.

But it's terrible bad idea to define operator outside namespace of its parameters (now you cut argument dependent lookup which is very usable for operators).

归途 2024-08-27 18:08:36

这是可能的 - 您可以将声明符括在括号中: 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 的观点,如果可能的话,最好将两者定义在同一个命名空间中。

It is possible - you can enclose the declarator in parentheses: friend A (::operator * (double lhs, const A& rhs));

You also need to forward-declare both the class and the function.

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) {
  //...
}

But I agree with Andreas that it would be better to define both in the same namespace if possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文