2016-03-04 71 views
1

我想要做的实际上是(简体但再现问题):升压递归variant

using my_variant_t = variant<int, function<void (recursive_wrapper<my_variant_t>)>>; 

也就是说,一个变体可以是int,或接受同类型的变体作为一种功能论据。但是,这当然失败了,因为‘my_variant_t’ was not declared in this scope。好的,接下来我尝试make_recursive_variant

using my_variant_t = make_recursive_variant<int, function<void (recursive_variant_)>>::type; 

这个编译。到现在为止还挺好。但是,当我尝试使用它...

my_variant_t x = [](my_variant_t p) {}; 

那么它失败......一大堆编译器输出的......但我认为Failed to specialize function template是重要的一点。

经过反复试验,我发现,我能得到它来编译,如果我写的,而不是像这样的λ:

my_variant_t x = [](recursive_variant_ p) {}; 

但是,这不是我本来期望。根据文档,我期望能够参考结果变体类型my_variant_t。而更糟的是,当我尝试调用此拉姆达...

x(42); 

然后失败,no match for call

我想我错过了某些东西或以某种方式滥用变体。有人能帮我解决这个问题吗?

回答

2

你只是期望太多的递归变体占位符系统。

这是一件事的图书馆发现并在模板参数列表的替代类型(如std::vector<_>,其中_是例如在recursive_variant_占位符)。

完全希望占位符在函数签名内被检测到(并替换)到模板参数列表中。

我不知道这是可以做到,但是这将是相当困难的(以得到正确的和硬的编译过程中,编译器)

+2

事实上,我认为这是MPL占位符的限制,他们在工作像'x <_1>','x <_1,_2>',但不是'x <_1(_2)>'。幸运的是,有一种'boost :: function'形式,它将存储函数的签名作为一系列类型(['function1 '](http://coliru.stacked-crooked.com/a/5e13873ed6fb9784))。关于函数调用操作符,他不能像这样使用它,因为'variant'没有定义它,他需要使用访问者,但我不确定它是否有意义(你怎么称呼'3(42 )'?或'f(42)'(其中f代表一个函数作为参数)?)。 – llonesmiz

+0

@cv_and_he✔使用boost函数1诀窍。你也是对的,调用变体函数是棘手的。我不得不把它写成'boost :: get >(x)(42);' –