我正在尝试构建一个程序,其源代码是我从互联网上下载的.当我尝试编译它时,我收到错误消息
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在结构之前移动内联定义,从友元函数声明中删除默认参数,并将其移动到内联定义来解决问题.它是否正确?
但更基本的是,我不明白为什么结构需要友元函数,因为它的成员无论如何都是公共的.这个问题的接受答案给出了一个答案(我的无知使我无法理解)依赖于参数的查找,但我不能看出它适用于这种情况.
删除友元函数声明,并将默认参数移动到内联函数定义是否有任何缺点?如果是这样,你能给我一个简单的例子吗?
但更基本的是,我不明白为什么结构需要友元函数,因为它的成员无论如何都是公共的.
这是一种误解.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)
使用class或struct声明一个类纯粹是一个惯例问题.因此,您的问题转化为"为什么课程需要朋友的功能?" 答案是:允许朋友访问私人字段.
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我也无法解释),并且与朋友们有什么好处的问题是正交的.