首页 > 解决方案 > 为什么结构需要友元函数?

问题描述

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

friend declaration specifying a default argument must be the only declaration

这是有问题的代码:

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

我找到了几个解决这个问题的问题,但这个问题相当深奥,我并不真正理解这些解释。这个问题的答案表明我可以通过移动mkLit结构之前的内联定义、从友元函数声明中删除默认参数并将其移动到内联定义来解决问题。这个对吗?

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

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

标签: c++

解决方案


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

这是一种误解。C++ 中没有结构和类,但 C++ 只有可以使用关键字structor之一声明的类class。唯一的区别是默认访问,即以下两个是相同的(除了他们的成员的顺序,如果你拿他们的地址很重要):

struct foo : private bar {
    int x;
private:
    int y;
};

和同样的class

class foo : bar {    
    int y;
public:    
    int x;
};

使用classstruct声明一个类纯粹是一个约定问题。因此,您的问题转化为“为什么一个类需要一个朋友功能?” 答案是:允许好友访问私有字段。

您链接的问题是关于内联定义友元函数而不是仅声明它,即

struct foo { 
    friend void foofriend() { /*put implementation here*/ }
};

对比

struct foo {
    friend void foofriend();
};

void foofriend() { /*put implementation here*/ }

这确实与 ADL 有关(我也无法解释),并且与朋友擅长什么的问题有点正交。


推荐阅读