我创建了一个定义自己的交换函数的仿函数。为简单起见,假设仿函数的运算符签名是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;
}
答案 0 :(得分:2)
来自std::swap
大型数据类型可以提供此功能的重载版本 优化其性能。值得注意的是,所有标准容器 以这样的方式专门化它只有几个内部指针 交换而不是他们的全部内容,使他们运作 恒定的时间。
标准库的许多组件(在std内)调用一个 不合格的方式允许非基本类型的自定义重载 被调用而不是这个通用版本:交换的自定义重载 声明在与提供它们的类型相同的命名空间中 通过依赖于参数的查找来选择此泛型 版本
免费功能std::swap(std::function)
的{{3}}说:
有效地调用lhs.swap(rhs)。
虽然成员函数std::function::swap
的{{3}}未指定任何类型。
所以,基本上,答案是“对此没有保证”,即使从第一个引用开始,大多数实现通过使用对swap
的非限定调用来调用用户定义的一个似乎是合理的。
答案 1 :(得分:0)
std::function::swap(function& other) noexcept
定义为:
效果:互换
的目标*this
和other
虽然目前尚不清楚它是否允许实现在目标上调用swap
,但由于目标中存在swap
成员,因此很自然地认为它没有。一旦目标被放入std::function
,就会被删除。这意味着在实现的情况下,实现需要花费大量精力(和运行时效率低)才能了解并调用用户定义的swap
(同时在用户定义的时候维护备份实现{ {1}}无效。)
此外,在可用时使用用户定义的交换,但只是在所有其他情况下交换指针,这将是相当不一致和令人困惑的。
在您的特定情况下,此函数标记为swap
,而您的noexcept
实现未标记,因此任何实现调用它都是不合法的(因为它可能会破坏{ {1}}合同)。