Effective STL 中文版记录(七)

Effective STL 章节(七)

——50条有效使用STL的经验(42/50)
函数子、函数子类、函数及其他



第三十八条、遵循按值传递的原则来设计函数子类

考虑的是函数嵌套的问题,将a函数作为参数传给b函数是不可行的,只能传递指针

而这样实际上是函数间以值进行传递,所以就需要这个a函数满足:

1、函数要小,否则传递的代价太大了
2、函数需要是单态的,虚函数的存在容易丢失类的元素信息

第三十九条、确保判别式是“纯函数”

判别式:以bool为返回值的函数
纯函数:返回值仅依赖参数的函数

这一条没什么好解释的,如果判别式的返回值不仅仅依赖输入参数,那判别式还有什么意义

第四十条、若一个类是函数子,则应使它可配接

什么是函数子?

函数子(也称为仿函数,functor)是一个表现得像函数的对象。它是一个重载了 operator() 操作符的类的实例。通过重载 operator(),你可以像调用函数一样使用这个类的实例。

举例:

class Add {
public:
    int operator()(int a, int b) const {
        return a + b;
    }
};

int main() {
    Add add;
    int result = add(2, 3); // 像调用函数一样调用对象
    return 0;
}

这里Add就是函数子,看着像函数,但定义上是类

怎么定义可配接?

可配接是指一个函数子能够与标准库中的配接器(如 std::bind, std::function, std::mem_fn 等)一起使用,或者能够适应各种算法和高阶函数的要求。

也就是说需要这个类能够和配接器一起使用,具体做法就是为类构建这些函数需要的内容

result_type:表示返回值类型。
argument_type 或 first_argument_type 和 second_argument_type:表示参数类型。

函数子如何变成可配接的?

继承自类unary_function、binary_function

第四十一条、理解ptr_fun、mem_fun和mem_fun_ref的来由

这几个配接器设计的初衷是为了保证函数调用不出错

f(x)// 语法1:f是一个非成员函数
x.f()// 语法2:f时成员函数,x是一个对象或对象的引用
p->f(); // 语法3:f是成员函数,p是一个对象指针

有的函数只能接受语法1,但是我们只有语法2的x,就需要这些函数去转换

但是C++ 11后有了lambda表达式、std::bind等函数,所以这几个配接器已经很少用了

第四十二条、确保less<T>与operator<具有相同的语义

举例:有一个类定义如下

class Widget
{
public:
	...
	size_t weight() const;
	size_t maSpeed() const;
	...
	bool operator < (const Widget& lhs, const Widget& rhs)
	{
		return lhs.weight() < rhs.weight();
	}
};

这里<表达的就是小于,那么再考虑一个问题,即multiset<Widget>,其默认比较函数是less<Widget>

通常情况下,less会调用operator<,此时两者基本上一样

但是如果为了某些条件,如这里以速度来排序,那么显而易见的方法是修改less函数:

template<> 
struct std::less<Widget> : public std::binary_function<Widget, Widget, bool>
{
	bool operator () (const Widget& lhs, const Widget& rhs) const 
	{
		return lhs.maxSpeed() < rhs.maxSpeed();
	}
}

但是这样容易误导其他程序员,因为他们不一定知道你对less进行了特化

为了不引起误会,最好是在简历multiset时就传入判断方式,使得代码清晰易懂

对less的特化,最好是不做,少做,确保它和operator<的语义一样,防止误会

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值