Boost C++ 库

……是世界上备受推崇且设计精良的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu《C++ 编码标准》

第 40 章 Boost.Typeof - Boost C++ 函数库
PrevUpHomeNext

第 40 章 Boost.Typeof

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 库的目的是提供一个基于库的解决方案,可以在语言级设施添加到标准并广泛可用之前使用。


PrevUpHomeNext