版权所有 © 2004, 2005 Arkadiy Vertleyb, Peder Holt
根据 Boost 软件许可版本 1.0 分发。(请参阅随附文件 LICENSE_1_0.txt 或复制 https://boost.ac.cn/LICENSE_1_0.txt )
目录
如今,许多模板库提供对象生成器,通过利用 C++ 模板参数推导功能来简化对象创建。考虑 std::pair
。为了实例化这个类模板并创建该实例化的临时对象,必须提供模板参数以及构造函数的参数
std::pair<int, double>(5, 3.14159);
为了避免这种重复,STL 提供了 std::make_pair
对象生成器。当使用它时,模板参数的类型从提供的函数参数中推导出来
std::make_pair(5, 3.14159);
对于临时对象来说,这就足够了。但是,当需要分配命名对象时,问题再次出现
std::pair<int, double> p(5, 3.14159);
对象生成器不再有帮助
std::pair<int, double> p = std::make_pair(5, 3.14159);
从对象初始化的表达式(在右侧)推导出对象(在左侧)的类型会很好,但当前的 C++ 语法不允许这样做。
上面的示例演示了问题的本质,但没有演示其规模。许多库,尤其是表达式模板库,创建了非常复杂类型的对象,并花费了大量精力将这种复杂性隐藏在对象生成器之后。考虑一个不起眼的 Boost.Lambda 仿函数
_1 > 15 && _2 < 20
如果有人想分配这样一个看起来无辜的仿函数的命名副本,她将不得不指定类似这样的东西
lambda_functor< lambda_functor_base< logical_action<and_action>, tuple< lambda_functor< lambda_functor_base< relational_action<greater_action>, tuple< lambda_functor<placeholder<1> >, int const > > >, lambda_functor< lambda_functor_base< relational_action<less_action>, tuple< lambda_functor<placeholder<2> >, int const > > > > > > f = _1 > 15 && _2 < 20;
不太优雅。为了解决这个问题(以及其他一些问题),C++ 标准委员会正在考虑对标准语言进行一些添加,例如 typeof/decltype
和 auto
(请参阅 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1607.pdf)。
typeof
运算符(或 decltype
,它是 typeof
的一种略有不同的变体)允许在编译时确定表达式的类型。使用 typeof
,上面的示例可以大大简化
typeof(_1 > 15 && _2 < 20) f = _1 > 15 && _2 < 20;
好多了,但仍然存在一些重复。auto
类型解决了其余的问题
auto f = _1 > 15 && _2 < 20;
Boost.Typeof 库的目的是提供一个基于库的解决方案,该解决方案可以在基于语言的功能添加到标准中并被广泛使用之前使用。