c++ - c++ 的朋友关键字是否意味着更多的访问私有?
问题描述
我编写了简单的类并定义了一个复制构造函数。然后添加朋友相等比较运算符并int
与Int
template <class T>
class Int {
public:
T value;
Int(const T& value_) : value(value_) {
;
}
friend bool operator==(const Int<T>& f, const Int<T>& s) {
return f.value == s.value;
}
};
int main() {
int a;
Int<int> x(a);
x == a;
}
编译成功。
如果我把它friend bool operator==(const Int<T>& f, const Int<T>& s);
变成一个非朋友模板。我得到一个编译器错误:
error: no match for 'operator==' (operand types are 'int' and 'Int<int>'
template <class T>
class Int {
public:
T value;
Int(const T& value_) : value(value_) {
;
}
};
template <class T>
bool operator==(const Int<T>& f, const Int<T>& s) {
return f.value == s.value;
}
int main() {
int a;
Int<int> x(a);
x == a;
}
这是否意味着友元函数允许特定的转换?
5 == x
也可以。
解决方案
c++ 的朋友关键字是否意味着更多的访问私有?
根据上下文,它可能会产生更多影响,是的。例如,一个friend
内联定义的函数,没有其他声明,只能通过参数相关查找找到,即使它是封闭命名空间的成员:
namespace foo {
struct bar {
friend void baz(bar const&) {}
};
}
int main() {
foo::bar bar;
// foo::baz(bar); // ill-formed, no member baz in foo
baz(bar); // Okay, it *can* be found by ADL
};
这与您的问题没有直接关系,但这operator==
就是查找朋友的方式。而且那个朋友本身也不是模板。当您实例化 时Int<int>
,这会将一个自由operator==
函数(同样不是模板)“注入”到名称空间Int
的成员中。当(通过 ADL)查找该运算符函数时x == a
,编译器会很高兴地考虑隐式转换a
为Int<int>
,因为我们可以进行隐式转换以匹配常规的自由函数。
说到转换……
我编写了简单的类并定义了一个复制构造函数。
你没有。这是一个带有参数的用户定义构造int const&
函数,而不是Int<int> const&
像复制构造函数那样。您定义了一个转换构造函数(因为它不是显式的),这正是编译器可以转换a
到Int<int>
上面的方式。
如果我转...
在您的第二个版本中,运算符是一个模板。它仍然由 ADL 查找。但是模板参数推导只考虑参数的确切类型。即, to 的两个参数都operator==
必须能够直接绑定到Int<T> const&
for some T
。Anint
不能直接绑定到Int<int> const&
,它需要转换。所以它与模板需要进行模板参数推导的参数类型不匹配。因此模板不能被实例化,并且不是候选模板。
这是否意味着友元函数允许特定的转换?
不,这不是友谊。这是模板与非模板业务。您可以定义operator==
没有友谊,但它必须是每个实例化的Int
:
template <class T>
class Int {
public:
T value;
Int(const T& value_) : value(value_) {
;
}
};
bool operator==(const Int<int>& f, const Int<int>& s) {
return f.value == s.value;
}
这也会让你main
的身材很好。但正如您所注意到的,单独声明它们并不是很有用,因此许多代码库将使用该friend
版本自动“注入”这个免费功能。
推荐阅读
- c# - IIS Blazor 应用程序(Intranet)需要输入 Windows 凭据
- docker - 在 docker 容器 (docker-compose) 中使用 nginx 运行 qgis 服务器
- migration - TYPO3 10.4:在 PSR-15 中间件中启动自定义 GET 参数
- javascript - Django 使用来自 Ajax 的成功数据更新模板 div
- microsoft-teams - MS Teams 选项卡 - 在 Android 和 iOS 客户端上下载文件
- java - NoClassDefFoundError 在运行时收到此错误?
- scala - Akka HighLevelHttp 从恢复 Future 返回 Route
- python - 计算数据框中两个地理编码之间的距离
- macos - iTerm2 现在将当前行保持在屏幕顶部,无法查看历史记录
- xml - 查询构建一对多结构