使用std::function改善模板的低效性
泛型编程中,模板会根据传入类型的不同,生成多种实例,相对低效。
模板编程:
#includeusing namespace std; //未使用函数包装器 template : &count"<<&count<<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(int argc, char *argv[]) { double y = 1.2; cout<<"Function pointer dub:"<<endl; cout<<" --"<<use_f(y,dub); cout<<"Function pointer square:"<<endl; cout<<" --"<<use_f(y,square); cout<<"Function pointer Fp:"<<endl; cout<<" --"<<use_f(y,Fp()); cout<<"Function pointer Fq:"<<endl; cout<<" --"<<use_f(y,Fq()); cout<<"Function pointer lambada1:"<<endl; cout<<" --"<T use_f(T v, F f) { static int count = 0; count++; cout<<"use_f count = "< " double u){return u*u;}); cout<<"Function pointer lambada2:"<<endl; cout<<" --"< double u){return u+2.5;}); return 0; }
模板编程的优势是高度抽象,将算法统一封装,但是其根据类型实例化的特性也造成了其低效性。
以上执行结果,通过查看静态模板函数中,静态数据的地址,其产生了5个函数实例。代码量受传入类型的影响产生了巨大的增量。
通过std::function来减少模板的实例化:
#include#include : &count"<<&count<<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(int argc, char *argv[]) { double y = 1.2; // cout<<"Function pointer dub:"<using namespace std; //使用函数包装器 template T use_f(T v, F f) { static int count = 0; count++; cout<<"use_f count = "< " // cout<<" --"< // cout<<"Function pointer square:"< // cout<<" --"< // cout<<"Function pointer Fp:"< // cout<<" --"< // cout<<"Function pointer Fq:"< // cout<<" --"< // cout<<"Function pointer lambada1:"< // cout<<" --"< // cout<<"Function pointer lambada2:"< // cout<<" --"< std::function<double(double)> fdub = dub; std::function<double(double)> fsquare = square; std::function<double(double)> fFp = Fp(); std::function<double(double)> fFq = Fq(); std::function<double(double)> lambada1 = [](double u){return u*u;}; std::function<double(double)> lambada2 = [](double u){return u+2.5;}; cout<<"Function pointer dub:"<<endl; cout<<" --"<<use_f(y,fdub); cout<<"Function pointer square:"<<endl; cout<<" --"<<use_f(y,fsquare); cout<<"Function pointer Fp:"<<endl; cout<<" --"<<use_f(y,fFp); cout<<"Function pointer Fq:"<<endl; cout<<" --"<<use_f(y,fFq); cout<<"Function pointer lambada1:"<<endl; cout<<" --"<<use_f(y,lambada1); cout<<"Function pointer lambada2:"<<endl; cout<<" --"<<use_f(y,lambada2); return 0; }
所有的静态变量只有一个地址,也就是说模板 函数只产生了一个实例,其类型只需要匹配是一个std::function
但是看来好像代码量并未减少甚至还有些许增多,下面我们通过优化来解决这个问题。
熊掌与鱼:
#include#include >(y,&dub); cout<<"Function pointer square:"<<endl; cout<<" --"<using namespace std; //模板中使用函数包装器 template T use_f(T v, std::function > f) { static int count = 0; count++; cout<<"use_f count = "<" : &count"<<&count<<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(int argc, char *argv[]) { double y = 1.2; //这里需要使得std::function cout<<"Function pointer dub:"<<endl; cout<<" --"<实例化为具体的对象 double double>(y,square); cout<<"Function pointer Fp:"<<endl; cout<<" --"< double>(y,Fp()); cout<<"Function pointer Fq:"<<endl; cout<<" --"< double>(y,Fq()); cout<<"Function pointer lambada1:"<<endl; cout<<" --"< double>(y,[](double u){return u*u;}); cout<<"Function pointer lambada2:"<<endl; cout<<" --"< double>(y,[](double u){return u+2.5;}); return 0; }
实例化与代码量都减少了,鱼和熊掌兼得。