版权所有 © 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 库的目的是提供一个基于库的解决方案,该解决方案可以在基于语言的工具添加到标准中并变得广泛可用之前使用。