2012-05-20 64 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。 –