2013-01-04 137 views
0

的地圖我想要一個映射字符串鍵到std::function<T()>std::function<T(int)>(但不能同時用於給定鍵)的映射。我收到一個編譯錯誤,似乎沒有std::function<T(...)>的模板。我希望能夠使用lambdas作爲值。包含std :: function <T()>和std :: function <T(int)>

首先,它是安全這樣存儲函數嗎?其次,如果是這樣,語法是什麼? (從地圖上檢索時,函數是否是一元函數或是否爲空函數)。如果不是這樣,那將是一個合理的選擇?指針殺死了拉姆達的想法,正確&hellip;

C++ 11是可以的。

+0

@OliCharlesworth,這是一種出路!在某些時候,我希望能夠隱藏這個,例如,只有一個獲得地圖類的方法。但我當然可以解決它。 –

+2

爲什麼不只是有兩個容器?由於無論如何您必須進行一些檢查,因此您知道如何調用函數,您還可以通過分隔兩種函數來進行檢查。 –

回答

5

一種替代方法是將nullary函數包裝在一個包含lambda的函數中,該函數接受一個參數,對此不做任何處理,只是調用包裝的函數。那麼你的地圖中的所有東西都是一元函數。

當然,如果你在檢索時知道函數是什麼類型的(我想你必須這樣做,否則它是沒用的!),那麼爲什麼不使用兩個地圖呢?

2

也許試試boost::variant

std::map<std::string, boost::variant<std::function<T()>, std::function<T(int)> > > 

無論如何,這似乎是一個XY question究竟是你想要做什麼?

+0

我想要一個工廠模式,其中「模子」對象(對象創建者)是無限的或一元的,並且映射通過類名稱或問題域中的等價名稱來鍵入。在創建最終對象之前,我可以在一元對象上使用std :: bind將它們變爲空。 –

2

std::function並不那麼重。你可以映射到一個包含每個結構的結構。你知道哪個是有效的,所以只能訪問那個。

如果您有需要,而不在任一作爲參數傳遞上都均勻工作模板代碼:

#include <string> 
#include <functional> 
#include <map> 
#include <tuple> 
#include <iostream> 
#include <math.h> 

template<typename T> 
using my_maps = std::tuple< std::map<std::string, std::function<T()>>, std::map<std::string, std::function<T(int)>>>; 


int main() { 
    my_maps<double> maps; 
    std::get<0>(maps)["pi"] = [](){ return 3.14; }; 
    std::get<1>(maps)["e^"] = [](int x){ return pow(2.7, x); }; 
    std::cout << std::get<1>(maps)["e^"](2) << "\n"; 
    std::cout << std::get<0>(maps)["pi"]() << "\n"; 
} 

這有兩張地圖,在訪問get<0>get<1>的差異。這樣做的好處是,如果您正在選擇要在模板中訪問哪兩個模塊,它可以靜態選擇0或1,並使用通用代碼。如果你不需要這個,只需要兩個std::map

A boost::variant也有效(映射到0ary或1ary函數的variant)。你也可以在帶有枚舉的struct中使用C++ 11 union(注意它將沒有默認構造函數,或者複製構造函數,除非你提供一個), - 基本上是一個枚舉(它的副本爲union)貧民窟boost::variant

相關問題