1

Foo.h:

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: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : 无法推断出 'const 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()
{

}
4

2 回答 2

2

您忘记将以下行添加到 Foo.cpp

#include <string>

那应该解决它。

修复它的原因是因为在std::string那里定义了 2 个对象之间的“<”运算符。由于std::map是一个关联数组,它将使用您指定的特定排序函数(作为模板的第三个参数,例如std::map<int, MyObj, MyIntCompareFunctor>)对键进行排序,或者默认使用键类型的 < 运算符,在您的情况下为std::string

PS 另外,通过引用传递字符串,而不是值:例如void foo(const std::string& bar){};

于 2012-05-20T22:58:35.730 回答
1

要在 STL 容器中使用某些类(如 ScreenBase),该类必须符合某些规范(特征)。在这种情况下,ScreenBase 必须是可复制构造的,因此您至少需要

ScreenBase(const ScreenBase& src) { CopyFromOther(src); }

void CopyFromOther(const ScreenBase& src) {... do the stuff ... }

复制构造函数。

还必须为 ScreenBase 定义“=”运算符。如果您已经有了复制构造函数并且它只是

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

为了避免询问有关 STL 容器的所有可能问题,您还可以阅读 SGI 关于 STL 的文档。它描述了使用地图/哈希表和其他任何东西所需的一切。

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


您对“派生类的实例”的评论提供了另一种见解。然后尝试将指针存储到 ScreenBase。

所以使用这个:

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

不会有警告,但当然需要额外的内存管理。

于 2012-05-20T22:45:16.183 回答