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

时间:2015-11-03 22:36:07

标签: c++ boost

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

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源库中常见的规范用法吗?

提前感谢您对此的看法!

1 个答案:

答案 0 :(得分:0)

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

通常,当存在多个相同“种类”的占位符时,它们是相关的,例如:

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);

将导致例如template_expr<something, ..., my_placeholder_t<2>, my_placeholder_t<1>>(见Expression templates)。

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

do_action(et,make_tuple(“忽略!”,“某事”,42));

do_action的实现可以解释占位符以从该元组中获取相应的元素,例如这就是bind库函数(std :: bind,boost :: bind,boost :: lambda :: bind,boost :: phoenix :: bind,boost :: mpl :: bind ...)全部倾向于做。

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