友元函数 in-class 定义只允许在非本地 class 定义中。这是什么意思?

Friend function in-class definition only allowed in non-local class definitions. What does it mean?

Here(见第 2 点描述)我读到友元函数 in-class 定义只允许在 non-local class 定义.

这是什么意思?

非本地 class 是 class 非本地。

局部 class 是在函数中定义的 class - 请参阅段落 "Local classes" on this page

"Friend function in-class definition" 指的是在 class 中声明和定义非成员函数的能力,class 是它所包含的 class 的友元。

class a_class
{
    friend std::ostream& operator<<(std::ostream& os, const a_class& x)
    {
        // ...
    }
};

非本地 class 定义是未在其他 class 主体中定义或未嵌入函数主体中的定义。

所以基本上你可以这样做:

#include <iostream>

struct NonLocal
{
  friend std::ostream& operator<<(std::ostream& os, const NonLocal& l)
  {
    os << l.x;
    return os;
  }

private:
  int x;
};

int main()
{
  NonLocal nl;
  std::cout << nl;
}

但你不能这样做:

#include <iostream>

int main()
{
  struct Local
  {
    friend std::ostream& operator<<(std::ostream& os, const Local& l) // this will fail to compile
    {
      os << l.x;
      return os;
    }

  private:
    int x;
  };

  Local l;
  std::cout << l;
}

来自cppreference.com

A class declaration can appear in namespace scope (in which case it defines an ordinary class), inside another class definition (in which case it defines a nested class), and inside the body of a function, in which case it defines a local class. The name of such a class only exists within the function scope, and is not accessible outside.

  • A local class cannot have static members
  • Member functions of a local class have no linkage
  • Member functions of a local class have to be defined entirely inside the class body
  • Local classes other than closure types (since C++14) cannot have member templates
  • Local classes cannot have friend templates
  • A local class inside a function (including member function) can access the same names that the enclosing function can access.
  • local classes could not be used as template arguments (until C++11)

[强调我的]

这意味着你不能这样做:

void function ()
{
    class X
    {
        int a;
        friend void friend_set(X& p, int i)
        {
            p.a = i;
        }
        public:
        void member_set(int i)
        {
            a = i;
        }
    };
}

Local-类是在函数内部定义的。