使用用户实现的交换交换std :: functions

时间:2013-07-31 08:58:03

标签: c++ swap functor

我创建了一个定义自己的交换函数的仿函数。为简单起见,假设仿函数的运算符签名是int(int)。如果我使用该仿函数初始化TWO std :: function,比如std_func1和std_func2,它们会交换它们是否调用了仿函数的用户实现的交换函数?提前谢谢。

以下是我的尝试:

#include <iostream>
#include <vector>
#include <boost/function.hpp>

using namespace std;

class myclass {

public:
  myclass(int n):data_(n,0){}

  void swap(myclass& rhs) {
    using std::swap;
    std::cout << "swapping myclass" << '\n';
    data_.swap(rhs.data_);
  }

private:
  vector<int> data_;
};


struct square {

  square(int n):B(n){}

  int operator()(int x) {
    return x*x;
  }

  myclass B;

  void swap(square& rhs) {
    using std::swap;
    std::cout << "swapping square" << '\n';
    B.swap(rhs.B);
  }
};

void swap(myclass& a, myclass& b) {
  a.swap(b);
}

void swap(square& a, square& b) {
  a.swap(b);
}



using myfunction = std::function<int (int)>;

int main () {
  myfunction myf1(square(10));
  myfunction myf2(square(20));
  myf1.swap(myf2);      /* does not use user-implemented swap functions */

  return 0;
}

2 个答案:

答案 0 :(得分:2)

来自std::swap

documentation
  

大型数据类型可以提供此功能的重载版本   优化其性能。值得注意的是,所有标准容器   以这样的方式专门化它只有几个内部指针   交换而不是他们的全部内容,使他们运作   恒定的时间。

     

标准库的许多组件(在std内)调用一个   不合格的方式允许非基本类型的自定义重载   被调用而不是这个通用版本:交换的自定义重载   声明在与提供它们的类型相同的命名空间中   通过依赖于参数的查找来选择此泛型   版本

免费功能std::swap(std::function)的{​​{3}}说:

  

有效地调用lhs.swap(rhs)。

虽然成员函数std::function::swap的{​​{3}}未指定任何类型。

所以,基本上,答案是“对此没有保证”,即使从第一个引用开始,大多数实现通过使用对swap的非限定调用来调用用户定义的一个似乎是合理的。

答案 1 :(得分:0)

std::function::swap(function& other) noexcept定义为:

  

效果:互换*thisother

的目标

虽然目前尚不清楚它是否允许实现在目标上调用swap,但由于目标中存在swap成员,因此很自然地认为它没有。一旦目标被放入std::function,就会被删除。这意味着在实现的情况下,实现需要花费大量精力(和运行时效率低)才能了解并调用用户定义的swap(同时在用户定义的时候维护备份实现{ {1}}无效。)

此外,在可用时使用用户定义的交换,但只是在所有其他情况下交换指针,这将是相当不一致和令人困惑的。

在您的特定情况下,此函数标记为swap,而您的noexcept实现未标记,因此任何实现调用它都是不合法的(因为它可能会破坏{ {1}}合同)。