C++ 提供了多个包装器 ,这些对象用于给其他编程接口提供一致或更好的接口,接下来介绍包装器function及其解决的问题。先看一组代码:
#include <iostream>
template<typename T,typename F>
T use_f(T v, F f)
{
static int count = 0;
count++;
std::cout << " use of count = " << count
<< ", &count= " << &count << std::endl;
return f(v);
}
class Fp
{
private:
double z_;
public:
Fp(double z = 1.0) :z_(z) {}
double operator()(double p) { return z_*p; }
};
class Fq
{
private:
double z_;
public:
Fq(double z = 1.0) :z_(z) {}
double operator()(double p) { return z_+p; }
};
double dub(double x) { return 2.0*x; }
double square(double x) { return x*x; }
int main()
{
using std::cout;
using std::endl;
double y = 1.21;
cout << "Function pointer dub is :" << endl;
cout << " " << use_f(y, dub) << endl;
cout << "Function pointer square is :" << endl;
cout << " " << use_f(y, square) << endl;
cout << "Function pointer Fp is :" << endl;
cout << " " << use_f(y, Fp(5.0)) << endl;
cout << "Function pointer Fq is :" << endl;
cout << " " << use_f(y, Fq(5.0)) << endl;
cout << "Lambda experssion " << endl;
cout << " " << use_f(y, [](double u) {return u*u; }) << endl;
cout << "Lambda experssion " << endl;
cout << " " << use_f(y, [](double u) {return u*2; }) << endl;
}
程序运行结果如下图所示:
每次调用中参数F都接受一个double类型的变量,返回一个double 类型的值,看起来只进行一次实例化,但其实不是,通过静态成员变量看出,实例化了五次。
如何解决这个问题,采用function 包装器。代码实例如下:
#include <iostream>
#include <functional>
template<typename T, typename F>
T use_f(T v, F f)
{
static int count = 0;
count++;
std::cout << " use of count = " << count
<< ", &count= " << &count << std::endl;
return f(v);
}
class Fp
{
private:
double z_;
public:
Fp(double z = 1.0) :z_(z) {}
double operator()(double p) { return z_*p; }
};
class Fq
{
private:
double z_;
public:
Fq(double z = 1.0) :z_(z) {}
double operator()(double p) { return z_ + p; }
};
double dub(double x) { return 2.0*x; }
double square(double x) { return x*x; }
int main()
{
using std::cout;
using std::endl;
using std::function;
double y = 1.21;
function<double(double)> ef1 = dub;
function<double(double)> ef2 = square;
function<double(double)> ef3 = Fp(5);
function<double(double)> ef4 = Fq(5);
function<double(double)> ef5 = [](double u) {return u*u; };
function<double(double)> ef6 = [](double u) {return 2 * u; };
cout << "Function pointer dub is :" << endl;
cout << " " << use_f(y, ef1) << endl;
cout << "Function pointer square is :" << endl;
cout << " " << use_f(y, ef1) << endl;
cout << "Function pointer Fp is :" << endl;
cout << " " << use_f(y, ef3) << endl;
cout << "Function pointer Fq is :" << endl;
cout << " " << use_f(y, ef4) << endl;
cout << "Lambda experssion " << endl;
cout << " " << use_f(y, ef5) << endl;
cout << "Lambda experssion " << endl;
cout << " " << use_f(y, ef6) << endl;
}
运行结果如下:
通过结果看出只进行了一次实例化。
代码还可以按照这种方式写:
#include <iostream>
#include <functional>
template <typename T>
T use_f(T v, std::function <T(T)>f)
{
static int count = 0;
count++;
std::cout << " use_f count = " << count
<< ", &count = " << &count << std::endl;
return f(v);
}
class Fp
{
private:
double z_;
public:
Fp(double z = 1.0) :z_(z) {}
double operator()(double p) { return z_*p; }
};
class Fq
{
private:
double z_;
public:
Fq(double z = 1.0) :z_(z) {}
double operator()(double p) { return z_ + p; }
};
double dub(double x) { return 2.0*x; }
double square(double x) { return x*x; }
int main()
{
using namespace std;
double y = 1.25;
cout << "Function pointer dub is :" << endl;
cout << " " << use_f<double>(y, dub) << endl;
cout << "Function pointer square is :" << endl;
cout << " " << use_f<double>(y, square) << endl;
cout << "Function pointer Fp is :" << endl;
cout << " " << use_f<double>(y, Fp(5)) << endl;
cout << "Function pointer Fq is :" << endl;
cout << " " << use_f<double>(y, Fq(10)) << endl;
cout << "Lambda experssion " << endl;
cout << " " << use_f<double>(y, [](double x) {return x*x; }) << endl;
cout << "Lambda experssion " << endl;
cout << " " << use_f<double>(y, [](double x) {return 2 * x; }) << endl;
}
运行结果: