lambda和std :: function之间的强制转换(关于结构继承自身偏特化版本)
关于C++ 特性不太熟悉,谷歌也因为不知道具体关键字而造成困难,于是又来请教大家。
代码是关于 lambda和std :: function之间的 无法进行强制转换 ,于是手动识别lambda 进行转换。
下面这里的结构体function_traits继承一个偏特化的版本是什么意思?
template <typename Function>
struct function_traits : public function_traits<decltype(&Function::operator())> {
};
原文链接(需fan墙):http://vitiy.info/c11-functional-decomposition-easy-way-to-do-aop/
测试代码(备注均为我自己添加,可能有错误)
#include <iostream>
#include <functional>
//using namespace std;
template <typename ...Args>
std::function<void(Args...)> wrapLog(std::function<void(Args...)> f) {
return [f](Args... args) { //捕获函数对象f
std::cout << "start" << std::endl;
f(args...);
std::cout << "finish" << std::endl;
};
}
template <typename Function>
struct function_traits : public function_traits<decltype(&Function::operator())> {
};
//lambda 转换为 std::function<void(Args...)> 需要知道 传入参数类型和返回值类型 ,这里进行萃取
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const> //Args...可变模板参数 ,因为不知道lambda将传入几个参数
{
//typedef ReturnType (*pointer)(Args...);
typedef std::function<ReturnType(Args...)> function;
};
template <typename Function>
typename function_traits<Function>::function //返回值类型 function_traits<Function>::function
to_function(Function& lambda) //函数名to_function,传入参数lambda
{
return typename function_traits<Function>::function(lambda); //将lambda传入function_traits<Function>::function
}
//functional里面有定义了个std::plus。如果把plus定义为global的,访问时在global查找定义就会和std::plus冲突,产生二义。
//auto plus = [](int a, int b) { std::cout << a + b << std::endl; }; //error,Plus不明确
std::function<void(int, int)> plus = [](int a, int b) { std::cout << a + b << std::endl; };
int main(int argc, char *argv[]) {
//这是简单的lambda,其中包含琐碎的计算:
//auto plus = [](int a, int b) { cout << a + b << endl; };
//lambda和 std :: function 无法完成转换
//auto loggedPlus = wrapLog(plus); //test1
//强制转换,OK,该行可以编译,但是很难看
auto loggedPlus = wrapLog(static_cast<std::function<void(int, int)>>(plus)); //test2
loggedPlus(2, 3);
//暂时最佳解决方案
auto loggedPluss = wrapLog(to_function(plus)); //通过调用to_function函数 将 lambda表达式plus 转换为std::function<void(Args...)> 形式
loggedPluss(2, 3);
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它并不一定要继承自己的偏特化。换一个也可以,比如这样:
这样看得清楚一些,
function_traits
是对外接口,但是需要function_traits_base
的辅助来获得其对应得std::function
特化。这里,由于
function_traits
与function_traits_base
都是只有一个类型模板参数,其生效得类型无交集(function_traits
只用于(实现了operator()
的)类类型,function_traits_base
只用于指向成员函数的指针),所以原来的实现里就都使用了function_traits
,没有引入另外的一个类型。