这两个内容没有什么联系, 只是放到一起做一下笔记.
1. lambda函数
python中有lambda函数的用法:
list(map(lambda x: x**2, [1, 2, 3, 4]))
输出:
1, 4, 9, 16
lambda函数是对于表达式不太长的较简单的功能, 尽量缩短代码提高可读性的一种手段. 实际上C++里面也有. 如果从例子入手的话, 比如说, 我要对一个类进行自定义排序. 定义如下的牛马类, 对于一个数组的牛马, 将收入从小到大排. 对于收入相同的, 将年龄从大到小排:
class CowHorse{
private:
std::string m_name;
int m_age;
double m_salary;
public:
CowHorse(const std::string& name, const int age, const double salary) : m_name(std::move(name)), m_age(age), m_salary(salary) {}
bool operator<(CowHorse& ch);
friend std::ostream& operator<<(std::ostream& os, CowHorse& ch);
};
方法一. 重载<运算符 因为sort函数默认是通过从小到大排序(std::less), 所以我们重载<运算符:
bool CowHorse::operator<(CowHorse& ch){
if (this->m_salary != ch.m_salary)
return this->m_salary < ch.m_salary;
else
return this->m_age > ch.m_age;
}
运行
void func(){
std::vector<CowHorse> arr;
arr.push_back(CowHorse("amy", 35, 3000));
arr.push_back(CowHorse("bob", 85, 3000));
arr.push_back(CowHorse("damengzi", 45, 9000));
arr.push_back(CowHorse("fool", 25, 1000));
sort(arr.begin(), arr.end());
for (auto& item: arr){
std::cout << item;
}
}
输出结果:
fool 25 1000
bob 85 3000
amy 35 3000
damengzi 45 9000
方法二. 仿函数 仿函数, 可以理解为函数对象, 即它可以是一个struct或class, 但用的时候当作函数来用, 为此需要重载()运算符. 定义自定义排序的类如下:
struct myCmp_{
bool operator()(CowHorse& ch0, CowHorse& ch1){
return ch0 < ch1;
}
};
调用sort时, 第三个参数传入实例化的myCmp_类:
sort(arr.begin(), arr.end(), myCmp_());
结果也是正确的. 方法三. 函数指针 当然, 更简洁的方式是直接定义函数(因为这个例子比较简单):
bool myCmpFunc(CowHorse& ch0, CowHorse& ch1){
return ch0 < ch1;
}
在调用sort时传入函数指针:
sort(arr.begin(), arr.end(), myCmpFunc);
方法四. lambda函数 lambda函数的格式为:
[返回值](参数){函数体}
或者
[](参数)->返回值类型{函数体}
因此可以这样写:
sort(arr.begin(), arr.end(), [&](CowHorse& ch0, CowHorse& ch1){return ch0 < ch1; });
其中[&] 的意思是按引用接收. 在这里用不用这个都可以.
2. 可变参数模板
我们知道, python中有*args与**kwargs用于定义函数的可变参数.
>>> def test(**kwargs):
... if 'name' in kwargs:
... print(kwargs['name'])
...
>>> test(name='asds')
因此, 我们在不确定函数输入参数的时候, 可以这样来用, 并且加条件判断即可. 这样有助于泛化性. C++中也有这项功能, 只不过不如python这么强大(C++中的可变参数不是哈希表, 不能向上面那样索引)
例如, 我们要定义一个函数, 打印它所有的参数值:
void func() {return;}
template<typename T, typename... Args>
void func(T t, Args... args){
std::cout << t;
func(args...);
}
int main(){
std::string name = "ajsdqwq";
func(name, name, name, name);
system("pause");
return 0;
}
输出:
ajsdqwqajsdqwqajsdqwqajsdqwq
其中, 模板参数包Args是一个类型的列表, 而函数参数包args是一个值的列表, 二者是一一对应的.
|