第18 章探讨 C++新标准.包装器,包装器 function 及模板的低效性,修复问题,其他方式
第18 章探讨 C++新标准.包装器,包装器 function 及模板的低效性,修复问题,其他方式
文章目录
18.5包装器
C++提供了多个包装器(wrapper,也叫适配器[adapter])。这些对象用于给其他编程接口提供更一致或更合适的接口。例如,第16章讨论了 bindlst 和 bind2ed,它们让接受两个参数的函数能够与这样的 STI算法匹配,即它要求将接受一个参数的函数作为参数。C++11提供了其他的包装器,包括模板 bind、men f和 reference_wrapper 以及包装器 function。其中模板 bind 可替代 bindlst和 bind2nd,但更灵活;模板 mem f让您能够将成员函数作为常规函数进行传递;模板reference_wrapper 让您能够创建行为像引用但可被复制的对象;而包装器fnction 让您能够以统一的方式处理多种类似于函数的形式。
下面更详细地介绍包装器function 及其解决的问题。
18.5.1包装器 function 及模板的低效性
请看下面的代码行:
answer =ef(g);
ef是什么呢?它可以是函数名、函数指针、函数对象或有名称的lambda表达式。所有这些都是可调用的类型(callabletype)。鉴于可调用的类型如此丰富,这可能导致模板的效率极低。为明白这一点,来看一个简单的案例。
首先,在头文件中定义一些模板,如程序清单18.6所示
程序清单18.6 somedefs.h
// somedefs.h
#include <iostream>
template <typename T, typename F>
T use_f(T v, F f)
{
static int count = 0;
count++;
std::cout << "use_f count = " << 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 q) {
return z_+ q; }
};
程序清单18.7 callable.cpp
// callable.cpp -- callable types and templates
#include <iostream>
#include <math.h>
using namespace std;
template <typename T, typename F>
T use_f(T v, F f