c++ - C++20 显式默认相等运算符
问题描述
我试图了解 C++20 中引入的新的默认比较运算符。我的问题是关于何时隐式定义显式默认的比较运算符。以下代码示例说明了这个问题:
#include <iostream>
struct B
{
operator bool() const { return true; }
};
struct D : B
{
bool operator==(const D&) const = default;
};
bool operator==(B, B) { return false; }
int main ()
{ D d;
std::cout << (d == d);
}
/* Outputs:
0 in gcc 10.1
1 in msvc 19.26
*/
该程序的输出依赖于编译器。似乎 MSVC 在遇到默认声明时为 D 类定义了 operator==,因此它不使用稍后为 B 类定义的 operator==。相比之下,gcc 等待 D 的隐式定义operator== 直到实际需要,此时为 B 定义的 operator== 在范围内并被使用。如果有的话,哪种行为是正确的?
一个相关的问题是,为什么不能为具有引用成员的类声明默认的 operator== ?我可以看到引用成员可能会给 MSVC 方法带来问题,因为当遇到 operator== 的默认声明时,引用成员可能会引用不完整的类型。使用 gcc 方法,在 gcc 尝试定义默认运算符之前,引用的类型总是完整的。
解决方案
GCC 在这里是错误的(考虑到它的结果并不奇怪)。在创建默认比较运算符的定义时,标准说:
比较运算符函数的默认定义中的名称查找是从与其函数体等效的上下文中执行的。
而默认函数的函数体是 where = default
is。因此,该bool operator==(B, B)
函数不应该对默认比较运算符的函数体可见。
推荐阅读
- python - 如何使用 shutil.make_archive 创建 zip64 存档
- flutter - 执行 Flutter 应用程序时出错 org-dartlang-debug:synthetic_debug_expression
- debugging - vscode c/c++ 调试器未附加 UNRESPONSIVE 扩展主机,'ms-vscode.cpptools'
- c# - 在 docker 上部署一个 net core 2 应用程序
- docker - 如何使用 Kubernetes 和 Skaffold 处理数据库迁移
- django - 无法使用 Django 登录,属性错误:AnonymousUser' 对象没有属性 '_meta'
- reactjs - 如何将类属性插件添加到 webpack
- c - 如何修改 TCP 拥塞算法?
- android - 如何使用 firebase 和 unity3d 解决“缺少依赖项”错误
- c - 在分叉进程中调用 Execve 的问题