2012-12-23 67 views
1

我有一個類場景是這樣的:find_if矢量和比較的成員變量

class Renderer; 

class Scene 
{ 
public: 
    Scene(const std::string& sceneName); 
    ~Scene(); 

    void Render(Renderer& renderer); 

    Camera& GetSceneCamera() const; 
    SceneNode& GetRootNode() const; 
    const std::string& GetSceneName() const; 


private: 
    const std::string mName; 
    Camera mSceneCamera; 
    SceneNode mRootNode; 
}; 

,然後我有場景的向量(vector<Scene>)。

現在給出一個字符串,我想遍歷這個場景的向量,如果在場景中找到名字,返回一個指向它的指針。這裏有一個天真的嘗試,但我得到的編譯錯誤:

Scene* SceneManager::FindScene(const std::string& sceneName) 
{ 
    return std::find_if(mScenes.begin(), mScenes.end(), boost::bind(&std::string::compare, &sceneName, _1)); 
} 

升壓抱怨數量的參數,所以我必須有語法錯誤..什麼是做這種正確的方法是什麼?

編輯:No instance of overloaded boost::bind matches the argument list

EDIT2:不C++ 11

由於

+0

如果遇到編譯錯誤,請添加確切的錯誤消息。 – Zeta

+0

沒有lambdas,C++ 11? –

+1

如果你只是使用'std :: find(mScenes.begin(),mScenes.end(),sceneName)'? –

回答

3

讓我們在此步驟。

find_if將爲矢量中的每個元素調用比較函數,當比較函數返回true時停止。該功能需要使用const Scene &參數進行調用。

我們可以寫一個這樣的(所有這些代碼是未經測試)

struct SceneComparatorName { 
    SceneComparatorName (std::string &nameToFind) : s_ (nameToFind) {} 
    ~SceneComparatorName() {} 
    bool operator() (const Scene &theScene) const { 
     return theScene.GetSceneName() == s_; 
     } 
    std::string &s_; 
    }; 

現在 - 你怎麼寫呢內嵌? 因爲你缺少調用GetSceneName您與boost::bind嘗試失敗了,你不能比較一個Scene &std::string

在C++ 11,很容易寫一個lambda但這正是上面什麼結構確實。

[&sceneName] (const Scene &theScene) { return theScene.GetSceneName() == sceneName; } 

但你不希望C++ 11,所以你必須寫類似:

boost::bind (std::string::operator ==, sceneName, _1.GetSceneName()); 

但是,這並不工作,因爲它會調用GetSceneName裏面調用,而不是綁定當調用由bind創建的仿函數時。

然而,Boost.Bind有重載運營商的支持,所以你可以這樣寫:

boost::bind (&Scene::GetSceneName, _1) == sceneName 

和完成。有關更多信息,請參閱文檔http://www.boost.org/doc/libs/1_52_0/libs/bind/bind.html#nested_binds

+0

如果容器而不是矢量是矢量或矢量>,那麼我應該寫什麼來與boost :: bind(&Scene :: GetSceneName,_1)== sceneName做同樣的比較? –

0

最短的方法可能是人工循環:

BOOST_FOREACH(Scene& scene, mScenes) { 
    if (scene.GetSceneName() == sceneName) return &scene; 
} 
return 0;