2016-03-04 74 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);' –