C++ 在向量中搜索对象的任何实例时出错

C++ 在向量中搜索对象的任何实例时出错,c++,vector,C++,Vector,我有一个向量叫做实体。我想检查它是否包含类NPC的任何实例。这就是我目前所拥有的 if (std::find(entities.begin(), entities.end(), NPC()) != entities.end()) std::cout << "contains NPCs" << std::endl; if(std::find(entities.begin()、entities.end()、NPC())!=entities.end() std::c

我有一个向量叫做实体。我想检查它是否包含类NPC的任何实例。这就是我目前所拥有的

if (std::find(entities.begin(), entities.end(), NPC()) != entities.end()) 
    std::cout << "contains NPCs" << std::endl;
if(std::find(entities.begin()、entities.end()、NPC())!=entities.end()

std::cout我的观点:
操作符==
是这里使用的错误工具,因为这不是测试相等性。这是一个测试,以查看给定的
实体是否为
NPC
。因此,我建议
std::find_if
<如果
允许我们指定不同的测试,则代码>查找

我能想到的最简单、最容易理解的测试是

bool isNPC(const Entity * const & entity)
{
    // a dynamic_cast returns nullptr if entity cannot be cast to an NPC *
    return dynamic_cast<const NPC*>(entity) != nullptr;
}
警告:这也将捕获
NPC
的子类

find_if_not
也应该引起您的兴趣

编辑 Lambda版本(C++14或更高版本。它是一个丑陋的吸盘,不比C++11中的自由函数版本好多少):

if(std::find_if(entities.begin()),
entities.end(),
[](自动和实体)->bool
{
返回动态_cast(实体)!=nullptr;
})!=实体。结束()
{

std::cout我的观点:
操作符==
在这里使用是错误的工具,因为这不是测试相等性。这是一个测试,看看给定的
实体是否是
NPC
。因此我建议
std::find_if
find_if
允许我们指定不同的测试

我能想到的最简单、最容易理解的测试是

bool isNPC(const Entity * const & entity)
{
    // a dynamic_cast returns nullptr if entity cannot be cast to an NPC *
    return dynamic_cast<const NPC*>(entity) != nullptr;
}
警告:这也将捕获
NPC
的子类

find_if_not
也应该引起您的兴趣

编辑 Lambda版本(C++14或更高版本。它是一个丑陋的吸盘,不比C++11中的自由函数版本好多少):

if(std::find_if(entities.begin()),
entities.end(),
[](自动和实体)->bool
{
返回动态_cast(实体)!=nullptr;
})!=实体。结束()
{


std::cout您的帖子似乎缺少一个。您需要告诉编译器如何通过重载
=
操作符来比较NPC。如果
std::find\u提供返回
true
false
true的方法,这取决于实体是否是NPC的实例。find将比较您传递的值n到向量中的元素。几乎可以肯定的是,您的错误是NPC没有为其正确定义运算符==此外,要找到相反的结果,请将测试从!=entities.end()更改为==entities.end(),则如果找不到if正文将执行。您的帖子似乎缺少a。您需要告诉编译器如何通过重载
=
运算符来比较NPC。您应该使用
std::find_if
提供方法,该方法将返回
true
false
,具体取决于实体是NPC的实例还是not.Find将比较您传入的值与向量中的元素。几乎可以肯定的是,您的错误是NPC没有为其正确定义运算符==此外,要找到相反的结果,请将测试从!=entities.end()更改为==entities.end(),那么如果没有找到,你的if体就会执行。这很好,但是有没有办法让它不捕获NPC的子类?另外,你能演示如何使isNPC成为lambda吗?@Gaud“有没有办法让它不捕获NPC的子类?”随便猜一下
find_if_not
做了什么。至于lambda,那将在稍后进行编辑。我同意,free函数更好,但是搜索函数有没有办法排除NPC的基类?我不能随便猜。我不知道。如果有办法,我会给你的答案打勾,我只是不想我很抱歉,我误读了你的第一条评论。
find_if_not
对这不起作用。因为
NPC
的子类是
NPC
s,我没有一个很好的方法来过滤它们。这导致了一个想法。如果你不想
NPC
的子类注册为
NPC
s、 为什么它们是子类?有点把整个is-a关系搞得一团糟。这很好,但有没有办法让它不捕捉NPC的子类?还有,你能展示一下如何让isNPC成为lambda吗?@Gaud“有没有办法让它不捕捉NPC的子类?”随便猜一下
find_if_not
做了什么。至于lambda,那将在稍后进行编辑。我同意,free函数更好,但是搜索函数有没有办法排除NPC的基类?我不能随便猜。我不知道。如果有办法,我会给你的答案打勾,我只是不想我很抱歉,我误读了你的第一条评论。
find_if_not
对这不起作用。因为
NPC
的子类是
NPC
s,我没有一个很好的方法来过滤它们。这导致了一个想法。如果你不想
NPC
的子类注册为
NPC
s、 为什么它们是子类?有点把整个is-a关系搞得一团糟。
void test(const std::vector<Entity *> & entities)
{
    if (std::find_if(entities.begin(), entities.end(), isNPC) != entities.end())
    {
        std::cout << "found NPC\n";
    }
    else
    {
        std::cout << "No NPCs\n";
    }
}
if (std::find_if(entities.begin(), 
                 entities.end(), 
                 [](auto & entity)->bool
                 {
                     return dynamic_cast<const NPC*>(entity) != nullptr;
                 }) != entities.end())
{
    std::cout << "found\n";
}
else
{
    std::cout << "not found\n";
}
template <class TYPE>
bool isChild(const Entity * const & entity)
{
    // a dynamic_cast returns nullptr if entity cannot be cast to an NPC *
    return dynamic_cast<const TYPE*>(entity) != nullptr;
}
std::find_if(entities.begin(), entities.end(), isChild<Ninja>)