使用std::tie进行一行交换



在python中我们可以交换两个变量

>>> a , b = b , a

可以在c++ 11中做类似的交换操作,如

void swap(int &a,int &b)
{
    std::tie(a,b) = std::make_tuple(b,a);
}
上面的

工作正常,并且在O3生成与

类似的汇编
void swap(int &a,int &b)
{
    int c = a;
    a = b;
    b = c;
}

但我的问题是它符合标准还是我错过了什么?还是像…一样的侥幸?

a = (a+b) - (b=a);

有顺序点问题

很好。

std::tiestd::make_tuple的调用可以以任意顺序发生,但它们不修改ab,只创建std::tuple s,分别引用ab并复制它们。只有在调用operator=时,才会通过对引用的赋值来进行任何修改。

std::swap用于此。它有一个通过使用临时值来交换值的默认实现,但对于某些类型(例如标准容器),它有一个优化的实现。

这里有一些更多的信息:http://en.cppreference.com/w/cpp/algorithm/swap

在c++中可以这样使用std::swap()模板:

#include <algorithm>
...
std::swap(a,b);

注意,在c++ 11中,它是在<utility>头文件中声明的。

如果可能的话,您的代码将这两个值都移动到tuple临时变量中,然后将它们复制回移动/复制的变量中。对于那些操作具有其通常语义的类型,它将安全工作,但对于更复杂的用户定义类型可能效率低下。显然,它要求类型支持所使用的移动或复制构造和赋值。(具体来说,赋值只发生在tuple成员设置之后,如果类型具有值语义,那么在赋值时,被赋值的移动或复制对象与tuple中的值是独立的)。

在相关类型可用的情况下,使用标准库的std::swap是最佳选择。许多其他类型可能会提供最适合它们的交换过载。如果您想要一种概念上简单的方法来为您自己的类型创建自定义swap函数,那么可以使用前面提到的代码。

最新更新