一个班轮使用std :: tie进行交换

时间:2015-09-24 11:11:21

标签: c++ c++11

在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);

哪个有序列点问题。

4 个答案:

答案 0 :(得分:6)

这很好。

std::tiestd::make_tuple的调用可以按任何顺序进行,但他们不会修改ab,只会创建std::tuple s分别引用ab的参考和副本。只有在调用operator=时,通过分配引用才能进行任何修改。

答案 1 :(得分:4)

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

以下是一些更多信息:http://en.cppreference.com/w/cpp/algorithm/swap

答案 2 :(得分:2)

如果可能,您的代码会移动 - 否则将两个值复制到tuple临时值,然后将它们复制回移动/复制的变量。它将安全地用于那些操作具有其通常语义的类型,但对于更复杂的用户定义类型可能效率低下。它显然需要类型支持移动或复制构造和使用的分配。 (具体来说,赋值仅在tuple成员设置后发生,如果类型具有值语义,则在赋值时,被分配的移动或复制对象独立于{{tuple中的值。 1}})。

如果涉及的类型可用,使用标准库的std::swap是最佳选择。许多其他类型可能提供最适合它们的交换过载。如果您想要一种概念上简单的方法来为您自己的类型创建自定义swap函数,那么可以使用您所显示的代码,但需遵守上述要求。

答案 3 :(得分:1)

在C ++中,您可以使用std::swap()模板,如下所示:

#include <algorithm>

...

std::swap(a,b);

请注意,在C ++ 11中,它在<utility>头文件中声明。