2012-05-20 66 views
1

foo.h中:麻煩添加元素爲std ::地圖

class Foo 
{ 
public: 
    Foo(void); 
    ~Foo(void); 

    void AddScreen(std::string name, ScreenBase &screenToAdd); 

private: 

    std::map<std::string, ScreenBase> m_screens; 
}; 

Foo.cpp中:

void Foo::AddScreen(string name, ScreenBase &screenToAdd) 
{ 
    m_screens[name] = screenToAdd; 
} 

最後行創建一個編譯錯誤C2784:「布爾的std ::操作者<(常量的std :: _樹< _Traits> &,常量的std :: _樹< _Traits> &) ':不能推導出模板參數的' 常量的std ::

註釋掉最後一行並且編譯成功。

我是新來的c + +(來自託管語言),不知道爲什麼我不能用這個填充地圖。

任何洞察力是讚賞。謝謝。

ScreenBase.h : 

    #pragma once 
    class ScreenBase 
    { 
    public: 
     ScreenBase(); 
     ~ScreenBase(); 

     virtual void Update(float tt, float dt); 
     virtual void Render(); 
    }; 

ScreenBase.cpp:

#include "pch.h" 
#include "ScreenBase.h" 

ScreenBase::ScreenBase(void) 
{ 
} 
ScreenBase::~ScreenBase(void) 
{ 
} 
void ScreenBase::Update(float tt, float dt) 
{ 

} 
void ScreenBase::Render() 
{ 

} 
+0

請向我們展示ScreenBase類 –

+0

添加的screenbase代碼。 –

+0

std :: map < - 這告訴我第二個參數將包含ScreenBase的實例,它是一個抽象類...我希望我沒有錯誤:) –

回答

2

你忘了添加下面一行到Foo.cpp中

#include <string>

這應該修復它。

解決該問題的原因是因爲在此定義了2個std::string對象之間的「<」運算符。由於std::map是一個關聯數組,因此它將使用您指定的特定排序函數(作爲模板的第三個參數,例如std::map<int, MyObj, MyIntCompareFunctor>)對鍵進行排序,或者它將默認使用鍵類型的<運算符,在您的情況下std::string

P.S.另外,通過引用傳遞字符串,而不是值: 例如void foo(const std::string& bar){};

+0

我認爲史蒂夫剛剛提出了他的問題,因爲不包括這個明顯的行:) –

+0

添加#include 確實導致它編譯成功,謝謝... –

1

要使用STL容器類的一些(如基篩),類必須符合某些規格(特徵)。在這種情況下,ScreenBase必須是可複製構建的,因此您至少需要複製構造函數。

此外,還必須爲ScreenBase定義「=」運算符。如果您已經拷貝構造函數,它僅僅是

ScreenBase& operator = (const ScreenBase& src) { CopyFromOther(src); return *this; } 

要避免問每一個可能的問題有關STL容器也可以讀取SGI的STL上的文件。它描述了使用諸如maps/hashtables和其他東西的所有東西。

http://www.sgi.com/tech/stl/


你對 「派生類的實例」 的評論給出了另一個見解。嘗試將指針存儲到ScreenBase中。

所以用這個:

std::map<std::string, ScreenBase*> m_screens; 

不會有任何警告,但當然,將需要額外的內存管理。

+0

感謝您對存儲指針而不是實例的見解。 –

+1

您可能想要存儲一個智能指針,而不是像C++ 11中的std :: shared_ptr。 –