c++ - 为什么结构需要友元函数?
问题描述
我正在尝试构建一个程序,其源代码是从 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++ 只有可以使用关键字struct
or之一声明的类class
。唯一的区别是默认访问,即以下两个是相同的(除了他们的成员的顺序,如果你拿他们的地址很重要):
struct foo : private bar {
int x;
private:
int y;
};
和同样的class
:
class foo : bar {
int y;
public:
int x;
};
使用class
或struct
声明一个类纯粹是一个约定问题。因此,您的问题转化为“为什么一个类需要一个朋友功能?” 答案是:允许好友访问私有字段。
您链接的问题是关于内联定义友元函数而不是仅声明它,即
struct foo {
friend void foofriend() { /*put implementation here*/ }
};
对比
struct foo {
friend void foofriend();
};
void foofriend() { /*put implementation here*/ }
这确实与 ADL 有关(我也无法解释),并且与朋友擅长什么的问题有点正交。
推荐阅读
- html - 我如何让这些表格部分适合屏幕的宽度?
- .net - .Net Core 2.1 与 IdentityServer4 Cookie 和基于 API JWT 的同一应用程序的身份验证
- python - 如何将非 SQLAlchemy 默认类型设置为 utf8 bin
- react-native - 如何在本机反应中从 responseJson 中删除 html 标签?
- javascript - 如何使用JS触发woocommerce产品库灯箱打开
- javascript - 为什么我需要使用 this.props.user.user.displayName 而不是 this.props.user.displayName?反应
- php - PHP 日期格式返回不正确的后缀 ('S')
- python - Python 解析 GitHub 文件
- outlook - iCal 文件不会将 VALARM 警报作为 Internet 日历导入 Outlook
- asp.net - System.Net.HttpWebRequest.GetResponse() 错误“您必须在调用 [Begin]GetResponse 之前将 ContentLength 字节写入请求流。”