我有一个名为实体的矢量。我想检查它是否包含NPC类的任何实例。这是我到目前为止所做的。
if (std::find(entities.begin(), entities.end(), NPC()) != entities.end())
std::cout << "contains NPCs" << std::endl;
当我尝试编译它时,我得到错误,“binary'==':找不到运算符,它采用'const NPC'类型的右手操作数”。
另外,有谁能告诉我如何检查相反的情况?也就是说,如何检查向量是否包含任何NPC?
编辑:
我将此添加到我的头文件
inline bool operator==(const NPC& lhs, const NPC& rhs)
{
return std::is_base_of<Entity, NPC>::value;
}
但我收到错误'std :: is_base_of':'_Der'的模板参数无效“
我以为我告诉它检查NPC是否是Entity类的子类,但也许我做错了。即使是这样,那甚至会解决问题吗?对不起,我只是不熟悉operaror重载。我对c ++很新。
答案 0 :(得分:2)
我的观点:operator==
是在这里使用的错误工具,因为这不是测试相等性。这是一项测试,以查看给定的Entity
是否为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;
}
我无法想到一个比这更复杂的理由。
isNPC
可能而且可能应该是一个lambda,但为了尽可能清楚这一点,我将它留给自由函数。模板此功能,您可以将其用于Entity
,Monster
的任何子项。
用法如下:
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";
}
}
警告:这也将捕获NPC
的子类。
here find_if_not
也应引起您的兴趣。
Lambda版本(C ++ 14或更新版本。它是一个丑陋的傻瓜,比C ++ 11中的免费功能版本好不了多少):
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>)
去寻找忍者。对于您自己搜索的每种类型,您不必一遍又一遍地编写相同的darn函数或lambda等效函数。
如果您使用一次或两次,请转到lambda。如果您怀疑自己将要找更多的孩子,请使用模板。除非现在有模板化的lambdas。那些会很酷。