[C++技巧篇1]enable_if,lambda
来源:互联网 发布:navicat for linux 64 编辑:程序博客网 时间:2024/06/06 05:39
enable_if
http://ju.outofmemory.cn/entry/30164
这个东西出现在C++11和boost中,两者用法略有区别,本文就以C++11中的std::enable_if为例,说说这个诡异的存在。大概说来,这个东西的实现是非常简单,甚至看上去略微幼稚的
template<bool, typename _Tp = void>struct enable_if { };template<typename _Tp>struct enable_if<true, _Tp>{ typedef _Tp type; };
这个东西最大的作用在于提供一些针对性的重载,当然,这需要配合一些类型判断之类的,这个技巧相信大家是能接受的,这里只说一个技巧,那就是返回值不同的重载。大家知道,重载必须是参数不同,只有返回值不同,这是不行的!但是,C++是个好语言,只要主人高兴,穿着黑丝被推倒也没关系的。。。于是,就有了这样的用法:
template <class T>typename std::enable_if<std::is_arithmetic<T>::value, int>::type foo( T &t){return static_cast<int>(t);}template <class T>typename std::enable_if<std::is_class<T>::value, T>::type & foo( T &t){return t;}
这确实是重载呢,客官且看下面的例子
foo(n1);Myclass a;foo(a);
这两次foo调用的分别是两个不同的东西,而且,这两个东西的参数是一样的,只是返回值不一样,类似的技巧和lambda配合更是天衣无缝啊!
lambda
此等神器的出现,直接使小麦抛弃了boost和C++11中的bind,那传参,那自由,那类型推导,真是完虐bind之流啊。不知道基本用法的同志请翻手册,此文不是入门手册。下面只说一个技巧,就是小麦最喜欢的用法
template <class FT>auto call(FT && f){return f();} //This is a wrong casecall([](){std::cout<<"do anything you want"<<std::endl;});
当然,上例是错误的,因为auto并不能让编译器推断出对应的类型,并且,如果是void的话,这里还不能return!当然,这是难不倒小麦的,我说过,C++是个好姑娘(语言)!首先,我们要能推断出返回值类型,这并不复杂,复杂的小麦也搞不定啊!
template<class F>struct deduce_function{};template<class Ret, class C, class... Args>struct deduce_function<Ret (C::*)(Args...) const>{ typedef std::function<Ret (Args...)> type; typedef Ret ret_type;};template<class Ret, class C, class... Args> struct deduce_function<Ret (C::*)(Args...)> { typedef std::function<Ret(Args...)> type; typedef Retret_type;};template<class F>struct function_res_traits{typedef typename deduce_function<decltype(&std::remove_reference<F>::type::operator())>::ret_type ret_type;};
有了返回类型,就好办多了,下面又是enable_if出场的时间了,
template<class FT>auto call(FT && f)-> typename std::enable_if<std::is_void<typename function_res_traits<FT>::ret_type>::value, void>::type{f();}template<class FT>auto call(FT && f )-> typename std::remove_reference<typename function_res_traits<FT>::ret_type>::type &&{ return f();}
就是这样,通过配合is_void判断返回类型是否为void,加上enable_if,就解决了lambda的返回值问题,实现了相同参数的重载。由于C++的故事比较丰富,所以。。。小麦下次再写吧!
下期预告:boost::function与boost::asio::yield,同样奇葩,敬请期待!
- [C++技巧篇1]enable_if,lambda
- enable_if
- enable_if
- enable_if
- enable_if
- [c#]: Lambda
- C#-Lambda
- c#Lambda
- c#lambda
- Java 8 Lambda 技巧
- 【c/c++】Lambda表达式
- 编程技巧:lambda与递归
- C#--Lambda表达式
- C++ox 之 lambda
- C#:Lambda 表达式
- C++lambda表达式
- C++lambda表达式
- C++lambda详解~读书笔记
- 大型网站技术架构
- 升级OSX High Sierra 10.13遇到一些问题及解决方法
- linux socket网络编程实例
- 自制ToolBox,支持自由展开多组
- typedef
- [C++技巧篇1]enable_if,lambda
- string相关的函数
- 结构体的大小
- MyBatis的Mapper接口以及Example的实例函数及详解
- 内存重叠
- SQLAlchemy用法指南
- jil
- Private感染扫描工具
- 1800万知乎用户的爬取