gpt4 book ai didi

c++ - 什么时候在 C++ 中提供自定义交换功能?

转载 作者:行者123 更新时间:2023-11-30 02:23:57 24 4
gpt4 key购买 nike

考虑一个自定义类 X,其中包含一些资源(为简单起见,此处用整数成员变量表示),带有 move 构造函数 (MC)、 move 赋值运算符 (MAO) 和自定义交换函数:

class X {
int i_;
public:
X(int i) : i_(i) { }
X(X&& rhs) = default; // move constructor
X& operator=(X&& rhs) = default; // move assignment operator
// X& operator=(X rhs) { std::swap(i_, rhs.i_); return *this; } // unifying assign. op.
friend void swap(X& lhs, X& rhs) { std::swap(lhs.i_, rhs.i_); }
int i() const { return i_; }
};

在以下基准代码中:

int main() {
int i1, i2;
std::cin >> i1 >> i2;

X x1(i1), x2(i2);
std::cout << x1.i() << x2.i();

swap(x1, x2);
std::cout << x1.i() << x2.i();

std::swap(x1, x2);
std::cout << x1.i() << x2.i();
}
  1. swap(x1, x2) 只是交换 2 个整数
  2. std::swap(x1, x2) 调用 1x MC 和 2x MAO
  3. 如果 MAO 被统一赋值运算符 (UAO) 替代,std::swap(x1, x2) 调用 3x MC 和 2x UAO

(使用 gcc/libstdc++ 测试)。

从表面上看,自定义 swap 非常有值(value),因为它避免了许多函数调用。但是,当我查看此程序的反汇编输出时:https://godbolt.org/g/RMfZgL , MC、MAO、UAO、swapstd::swap 的所有功能都直接内联到 main (带有 -O2 标志的 gcc/clang)。此外,程序中没有创建 X 类型的对象,它仅适用于机器代码级别的整数。

因此,在我看来,没有理由为像X 这样的类提供自定义swap 函数。

问题:

  1. 假设编译器将优化 std::swap 中对 MC 和 MAO/UAO 的调用是一种好习惯吗?或者,我是否应该为所有自定义类定义自定义 swap
  2. 自定义 swap 对哪些类别真正有益?

最佳答案

你应该遵循0的规则。

非资源管理类应该有默认的 move/复制/分配/销毁。

资源管理类应该只关心管理资源。

您的代码不管理资源。所有复制/move 明智的东西都应该是默认的。

swap 是 move 的特例。如果您是资源管理类型,您可能还想编写它。但是,与大多数事情一样,它是一种优化,只有在证明它对性能有影响的情况下,您才应该进行此类优化。

它可能会对性能产生影响的一个例子是,如果您拥有一个永不为空的资源拥有类型并且该资源不是免费的,那么创建一个临时对象会不可避免地产生成本。 std::swap 默认情况下穿过一次性对象。自定义交换可以避免这种情况。

或者,一种类型,它是 move 元素的廉价缓冲区;创建这么大的缓冲区可能会产生实际成本。

否则,不要这样做。并测试您是否这样做有帮助。自定义交换是针对特定情况的 move 优化。

关于c++ - 什么时候在 C++ 中提供自定义交换功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45640000/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com