【问题标题】:Unexpected error about no return type in friend declaration in C++关于 C++ 中友元声明中没有返回类型的意外错误
【发布时间】:2017-12-15 11:31:57
【问题描述】:

我正在尝试使用 g++ 编译以下代码(从实际使用中简化):

namespace A {
    class B;
}

A::B operator+(A::B a, A::B b);

namespace A {
    class B {
    private:
        int i;
    public:
        B() : i(0) {}
        B(int j) : i(j) {}

        friend B ::operator+(B a, B b);
    };
}

A::B operator+(A::B a, A::B b) {
    return A::B(a.i + b.i);
}

int main() {
    A::B a(1), b(2);
    A::B c = a+b;
    return 0;
}

据我所知,B 类中的朋友声明是正确的,并且需要 :: 全局范围声明,否则编译器会假定 A::operator+(B a, B b) 的意思。

然而,在编译这个时,gcc 给出了错误信息

ISO C++ forbids declaration of ‘operator+’ with no type

我不知道如何解决这个问题。之后的错误消息给人的印象是 gcc 忽略了该行中 B 和 :: 之间的空格,而是将其解释为 B 的成员函数的朋友声明。我该如何告诉它我想要什么?

【问题讨论】:

  • 通常我会在类内部声明友元函数,我只会像友元 int operator+() 一样声明它,而在类外部,我可以像 int B::operator+ 一样定义它() .. 不知道这是否适用于你的情况
  • @SIMEL:与我无关:这里没有const& T
  • 不知道为什么您的代码不起作用(因为在另一个命名空间中移动 operator+ 是有效的),但您可以使用 that,这无论如何都更惯用。
  • 编译器确实忽略了B:: 之间的空格。那是因为空间无关紧要:您可以将所有提到的A::B 替换为A :: B 而不会改变含义。您可以在类名和范围限定符之间放置空格。这不是您遇到此问题的原因。

标签: c++ function class namespaces friend


【解决方案1】:

通过以下方式在类定义中声明友元运算符

friend B (::operator+) (B a, B b);

或者喜欢

friend B (::operator+(B a, B b));

否则编译器认为它是类的成员函数,没有明确的返回类型(隐含 int)

friend B::operator+(B a, B b);

虽然这样声明会更好

friend B (::operator +)( const B &a, const B &b);

【讨论】:

  • 我不同意朋友 B 的建议 (::operator +)( const B &a, const B &b);使用它还需要定义右值变体,这取决于类型是否在实践中具有性能优势。但括号建议是关键,谢谢。
  • @davidv1992 不需要为右值声明运算符。为常量引用声明它就足够了。否则会有构造函数和析构函数的冗余调用。
【解决方案2】:

:: 被视为应用于B 的范围解析运算符:friend B::operator+(B a, B b); 因此,要使其工作,您应该在返回的类型名称之后放置friend 关键字:

B friend ::operator+(B a, B b);

check working code online

【讨论】:

    猜你喜欢
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多