所有由木头云发布的文章

C++的杂七杂八:使用模板元编程操作类型集合

群里有个朋友要实现这么一个功能:如何在编译期把一个函数类型的参数减少一个。
简单来说,就是实现下面这个模板:

根据输入的编译期整数,把函数参数表里对应的参数干掉一个。
为了实现这种功能,我们需要操作变参模板的参数包。比如像这样:

上面这段代码的思想很简单,把模板参数包的第N个参数删掉,然后再将它重新展开成函数的参数表。而types的定义可以非常简单:

如果定义了一组对types类型做操作的算法,那么我们就可以把参数包放入types中,然后对它做这样那样的事情。。

看到这里,不知道有没有朋友想起来很久很久以前,Loki库里的TypeList。现代的C++当然不需要再像当年那样用外敷类和繁琐的宏来实现这个,使用变参模板加模板元就好了。 继续阅读C++的杂七杂八:使用模板元编程操作类型集合

C++的杂七杂八:constexpr与编译期计算

1. 编译期计算

我们先来看一段求阶乘(factorial)的算法:

很明显,这是一段运行期算法。程序运行的时候,传递一个值,它可以是一个变量,也可以是一个常量:

如果程序仅仅像这样传递常量,我们可能会希望能够让它完全在编译的时候就把结果计算出来,那么代码改成这样或许是个不错的选择: 继续阅读C++的杂七杂八:constexpr与编译期计算

C++的杂七杂八:如何实现一个简单的bind

这篇文的草稿我是在2014年5月11号开始打的,可是拖拖拉拉直到现在才真正动笔写,自己对自己也是醉了。。
之所以写bind而不是什么其他的东西,是因为bind在各种C++的utility里面可以说是最能体现出“利用语言本身来拓展语言功能”这一特征的了。

在C++98/03的时代,人们为了让C++具有把函数和参数打包成闭包(closure)这一能力而发明了bind,从而使C++不仅可以存储算法执行的结果,还可以打包算法和算法的传入参数,存储算法执行的动作,直到调用这个闭包的时候才释放出参数并参与算法计算。有了这个东西之后,再配合可以存储任何可调用体的function对象,不少面向对象里麻烦的调用关系可以被简化到不像话的地步(具体可参看此文:以boost::function和boost:bind取代虚函数)。

在C++98/03下实现一个好用的bind是痛苦的。看看Boost.Bind,还有我自己,为了实现一个完善的bind折腾遍了C++的奇巧淫技……这是很划不来的,平时学习或兴趣玩一玩还可以,真在项目工程里这样做了,如何维护会是一个很头痛的事情。

在C++11里事情变得很不一样了。首先stl里就已经给我们提供了好用的std::bind,然后再就是语言本身的进化,让“写一个bind”之类的事情变得无比简单。 继续阅读C++的杂七杂八:如何实现一个简单的bind

C++的杂七杂八:萃取函数(可调用体)的各种属性

在C++中,存在“可调用对象(callable objects)”这么一个概念。这里我直接摘录C++11标准《ISO/IEC 14882:2011》,§ 20.8.1 Definitions:

A callable type is a function object type (20.8) or a pointer to member.
A callable object is an object of a callable type.

同时,再根据 § 20.8 Function objects:

A function object type is an object type (3.9) that can be the type of the postfix-expression in a function call (5.2.2, 13.3.1.1). A function object is an object of a function object type. In the places where one would expect to pass a pointer to a function to an algorithmic template (Clause 25), the interface is specified to accept a function object. This not only makes algorithmic templates work with pointers to functions, but also enables them to work with arbitrary function objects.

我们可以总结出callable objects的基本定义: 继续阅读C++的杂七杂八:萃取函数(可调用体)的各种属性