c++ - 用户定义交换方法的可行性
问题描述
考虑到这个话题,我有一个想法(鉴于我正在谈论),应该只为不提供 的类型提供C++11
用户定义,更准确地说是运算符(因为我认为更常见的是虽然缺少操作员);or the and/or operator 有一些不希望发生的副作用。swap
move semantic
move assignment
move ctr
move assignment
move ctor
move assignment
让我们看看示例:[与链接主题中的相同]
class remote_connection
{
public:
int socket_fd;
friend void swap( remote_connection& lhs, remote_connection& rhs ) = delete;
}
由于我们没有提供用户定义swap
的代码,试图交换一个remote_connection
类型的对象调用一个swap
实例化的代码,std::swap
从而导致一个移动构造和两个移动分配发生(如@1201ProgramAlarm所示)。
因此,要交换对象,编译器会发出以下问题:一个对 a 的函数调用std::swap
,一个对 a 的调用move ctr
和两个对move assign
运算符的调用。这导致 3 个int
副本进行实际交换。
结果:4 个函数调用和3 个副本。
让我们实现一个swap
方法:
class remote_connection
{
public:
int socket_fd;
friend void swap( remote_connection& lhs, remote_connection& rhs )
{
using std::swap;
swap( lhs.socket_fd, rhs.socket_fd );
}
}
由于我们提供了一个用户定义swap
的代码,试图交换一个remote_connection
类型的对象调用这个用户定义的代码,swap
这会导致发生 3 个副本int
(从 rhs 创建一个 tmp,将一个 lhs 复制到 rhs,将 tmp 复制到 lhs )。
因此,要交换对象,编译器会发出问题:一个对 a 的函数调用swap
(由 ADL 发现),一个对 a 的调用std::swap(int&, int&)
。这也导致 3 个int
副本进行实际交换。
结果:2 个函数调用和3 个副本。
用户定义的交换赢了,但是如果我们在类中添加一些成员会怎样:
class remote_connection
{
public:
int socket_fd;
int a, b, c, d, e;
friend void swap( remote_connection& lhs, remote_connection& rhs )
{
using std::swap;
swap( lhs.socket_fd, rhs.socket_fd );
swap( lhs.a, rhs.a );
swap( lhs.b, rhs.b );
swap( lhs.c, rhs.c );
swap( lhs.d, rhs.d );
swap( lhs.e, rhs.e );
}
}
这里我们有:8个函数调用和6 个副本。但如果我们不提供 user-defined swap
,我们将有:4 个函数调用和6 个副本。
因此,似乎无论我们拥有什么类(派生自具有大量成员的类,由大量内置和用户定义类型的子对象组成),恕我直言,不提供用户定义的swap
. 不仅如此,而且这样的swap
很难支持(如果我们在课堂上更改了某些内容而忘记反映这些更改,swap
我们会感到惊讶。)
move ctr
所以问题是:“如果我们在/中没有副作用move assign
operator
并同时提供它们,我们是否必须实现 user-defined swap
,或者在这种情况下依赖stl
提供的一个是一种好习惯?”
抱歉这么多,我不是母语人士:)
PS我忘了补充一点,恕我直言,swap
如果我们要实现一个copy-and-swap
成语并且我们已经实现了一个move assignment
运算符,那么我们需要一个用户定义的。
解决方案
推荐阅读
- php - RewriteRule - 丢弃尾部斜杠
- r - 传递给函数的顺序数据帧
- arrays - 带有数组的 SAS Find()
- javascript - 如何在 Angular 中预填充 ngselect?
- javascript - 调用 onBlur 时,Firefox 中的relatedTarget 为空
- python - 将 sql 表放入 python 错误。怎么了?
- javascript - 没有参数的异步递归函数会泄漏内存或堆栈溢出吗?
- azure - Azure Databricks 群集 API 身份验证
- azure - Application Insights 警报。通过 ARM 模板设置抑制时间
- php - 如何使用 wp_get_theme 修改 singlepost.php