2014-03-12 51 views
1

我有以下的工廠函數:boost phoenix new_的地圖?

std::auto_ptr<IPath> PathFactory(std::string const& branch_type, CPathModel const& path_model) 
{ 
    using namespace boost::assign; 
    using namespace boost::phoenix::placeholders; 

    typedef boost::function<IPath* (CPathModel const&)> PathFactoryFunction; 
    typedef boost::unordered_map<std::string, PathFactoryFunction> FactoryMap; 

    static FactoryMap factory_map = map_list_of<std::string, PathFactoryFunction> 
     ("plu",   &phx::new_<CPluPath>) 
     ("time_of_day", &phx::new_<CTimeOfDayPath>) 
     ("probability", &phx::new_<CProbabilityPath>) 
     ; 

    std::auto_ptr<IPath> new_path; 

    FactoryMap::const_iterator it = factory_map.find(branch_type); 
    if (it != factory_map.end()) 
    { 
     new_path.reset(it->second(path_model)); 
    } 

    return new_path; 
} 

此代碼不能編譯,請注意,我用C++ 03。我在這裏要做的是創建一個字符串映射到小函數對象,可以分配一個特定類型的對象。每個對象都採用相同類型的單個施工參數(CPathModel const&)。

phx::new_有幾個重載,所以它可能不是直接引用它的最好主意,但我希望每個人都可以幫助我找到一種方法來使用boost :: phoenix清理此代碼並使測繪工作優雅。

在這一點上看起來更簡單,只需定義一個帶有過載的()運算符的小模板類,該運算符采用該參數並且僅在new T(p1)之內。但這是樣板,似乎很簡單,提升必須有一個很好的解決方案...

回答

1

鳳凰是用於懶惰仿函數。

在這裏你不需要任何東西(這裏有一個表達式模板)。

所以,你可以使自己的工廠方法的模板:

template <typename PathType> IPath* make_path(CPathModel const& model) { 
    return new PathType(model); 
} 

並使用它:

static FactoryMap factory_map = map_list_of<std::string, PathFactoryFunction> 
    ("plu",   &make_path<CPluPath>) 
    ("time_of_day", &make_path<CTimeOfDayPath>) 
    ("probability", &make_path<CProbabilityPath>) 
    ; 

完成任務。

雖然在這一點上,使用地圖查找工廠沒有任何好處。事實上,這只是浪費。一個簡單的開關[1]優。更多的是,因爲它刪除了std::function中的類型擦除(隱式虛擬多態)。

[1]事實上,它需要被鏈接if S,或者你可以在Perfect Hash

+0

切換它是一個過早的優化有利於如果鏈接在地圖嗎?當然,性能可能會有所不同,但在我們可以分析整體應用程序性能並確定並理解瓶頸之前,更改此代碼可能不會帶來任何有意義的收益。 –

+0

這不是關於優化。這是關於清晰度。想想看。你甚至不能在沒有諮詢stackoverflow的情況下把它關掉......(現在我知道所有關於嘗試僅僅爲了挑戰或者尋求更多優雅的事情,我也是這樣做的,但是我已經準備好垃圾代碼了它不拉它的重量)。在這種情況下,映射(在堆分配的基於節點的容器中的非線性查找)和std ::函數都是不必要的複雜性。它被視爲過早的悲觀化。我會說吻。沒有與優化。 – sehe

+0

沒錯,在最終完成這個工作之後,結果看起來像是複雜的垃圾:-( –

相關問題