C++-占位符是如何工作的(特别是在boost::type_erasure中)



我正在努力了解类型擦除技术,正如这里所讨论的,并在adobe::poly和Boost::TypeErasure中实现。不幸的是,我似乎错过了对占位符的基本理解;我目前正在努力理解boost文档中的以下代码(此处):

std::vector<int> vec;
any<has_push_back<_self, int>, _self&> c(vec);

我的问题如下:

1) 我相信我已经看到了一些占位符的例子——在lambdas、Boost MPL等中。似乎有一种惯例用前导下划线来指定这些占位符。我的理解是,根据标准,至少在文件/全局范围内,带有前导下划线的标识符是保留的。如果这是正确的,则表明占位符是在某个地方定义的。那么,"_self"占位符是在哪里以及如何定义的呢?(我在库中看到一个声明,但仅此而已——没有实现。这就是所需的全部吗?)

2) 据推测,每个库都定义了它们的占位符,但它们的名称通常是相同的(例如,"_1"、"_2"…)。因此,当在一个翻译单元中同时使用多个库时,开发人员通常需要明确地限定使用,以避免歧义/冲突?或者ADL在某种程度上缓解了这种情况?最好的做法是明确限定占位符,还是为了避免过多的"语法噪音"而避免这样做?

3) 在上面的代码中,在"any"的实例化过程中,"_self"似乎被std::vector替换了。这是从这个变量声明/初始化语句中隐含地推导出来的吗?(也许是通过ctor模板??)如果不是,这是如何工作的?

4) 这些占位符总是模板参数的类型说明符吗?这是元编程/lambda源库中常见的规范用法吗?

提前感谢您对此的思考!

一般来说,占位符只是可以在模板元编程中"切换"的唯一类型。

通常,当有多个相同"种类"的占位符时,它们是相关的,例如:

template <int N>
struct my_placeholder_t {
    enum { value = N };
};
typedef my_placeholder_t<0> _0;
typedef my_placeholder_t<1> _1;
typedef my_placeholder_t<2> _2;
...

这种关系只会使编写通用代码变得更容易,但对最终用户来说并不重要:

typedef /*implementation-defined*/ _0;
typedef /*implementation-defined*/ _1;
typedef /*implementation-defined*/ _2;
...

实现将在稍后阶段使用占位符。占位符通常以一种类型编码:

auto et = foo(_2, _1);

将产生例如CCD_ 1的对象(参见表达式模板)。

在稍后的阶段,这些类型将被"解释",例如当你这样做时:

do_action(et,make_tuple("忽略!","某物",42));

do_action的实现可以解释占位符,以从该元组中获取其相应的元素,例如,这就是bind库函数(std::bind、boost::bind、boost::lambda::绑定、boost::phoenix::绑定,boost:::mpl::bind…)的所有功能


在Boost TypeErasure中,占位符_self主要用于指定成员函数概念规范中this参数的资格。

最新更新