为什么结构需要友元函数?

sau*_*atz 1 c++

我正在尝试构建一个程序,其源代码是我从互联网上下载的.当我尝试编译它时,我收到错误消息

friend declaration specifying a default argument must be the only declaration
Run Code Online (Sandbox Code Playgroud)

这是违规代码:

typedef int Var;
struct Lit {
    int     x;
    // Use this as a constructor:
    friend Lit mkLit(Var var, bool sign = false);
    bool operator == (Lit p) const { return x == p.x; }
    bool operator != (Lit p) const { return x != p.x; }
    bool operator <  (Lit p) const { return x < p.x;  } 
inline  Lit  mkLit(Var var, bool sign) { Lit p; p.x = var + var + (int)sign; return p; }
Run Code Online (Sandbox Code Playgroud)

我发现了几个解决这个问题的问题,但事情是相当深奥的,我并不真正理解这些解释.这个问题答案表明我可以通过mkLit在结构之前移动内联定义,从友元函数声明中删除默认参数,并将其移动到内联定义来解决问题.它是否正确?

但更基本的是,我不明白为什么结构需要友元函数,因为它的成员无论如何都是公共的.这个问题的接受答案给出了一个答案(我的无知使我无法理解)依赖于参数的查找,但我不能看出它适用于这种情况.

删除友元函数声明,并将默认参数移动到内联函数定义是否有任何缺点?如果是这样,你能给我一个简单的例子吗?

for*_*818 5

但更基本的是,我不明白为什么结构需要友元函数,因为它的成员无论如何都是公共的.

这是一种误解.C++中没有结构和类,但C++只有可以使用其中一个关键字struct或者声明的类class.唯一的区别是默认访问,即以下两个是相同的:

struct foo : private bar {
    int x;
private:
    int y;
};
Run Code Online (Sandbox Code Playgroud)

和以下一样class:

class foo : bar {
     int y;
public:
     int x;
};
Run Code Online (Sandbox Code Playgroud)

使用classstruct声明一个类纯粹是一个惯例问题.因此,您的问题转化为"为什么课程需要朋友的功能?" 答案是:允许朋友访问私人字段.

你链接问题是关于定义友元函数内联与仅仅声明它,即

struct foo { 
    friend void foofriend() { /*put implementation here*/ }
};
Run Code Online (Sandbox Code Playgroud)

VS

struct foo {
    friend void foofriend();
};

void foofriend() { /*put implementation here*/ }
Run Code Online (Sandbox Code Playgroud)

这确实与ADL有关(tbh我也无法解释),并且与朋友们有什么好处的问题是正交的.