这是我的模板功能:
template<class DataStruct>
static bool isPlayerIn(DataStruct players, int id){
for(DataStruct::iterator player = players.begin();
player != players.end(); ++player){
if((*player)->_id == id){
return true;
}
}
return false;
}
我希望它能够将玩家作为矢量和地图,或任何其他STL。我不能使用算法查找,因为我正在搜索&#34;播放器&#34;,谁的内部字段id与给定参数相同。这项工作有什么办法吗?
抱怨:
(*player)->_id
因为它不知道玩家是ptr到玩家类的ptr。
答案 0 :(得分:1)
使用C ++ 11,您可以轻松地将find_if
与lambda function:
[=](const typename DataStruct::value_type &v){return v._id == id;}
你总是使用像
这样的东西auto has_id = [=](const typename DataStruct::value_type &v){return v._id == id;};
return std::find_if(
std::begin(players),
std::end(players),
has_id) != std::end(players);
答案 1 :(得分:1)
由于您要求它,您可以将lambda放在isSameID
函数中,如果它将在多个地方使用。当你进行代码维护时,它也可能使它更容易阅读。
template <class ContType>
bool isSameID(ContType cont, int id) {
auto found = find_if(begin(cont), end(cont), [id] (auto item) {
return item->_id == id;
});
return found != end(cont);
}
此函数假定容器已通过并且您正在使用c ++ 14。
更新1:
使其适用于map
和vector
的最快方法是将_id
检索从函数中分离出来,让编译器选择正确的方法来获取_id
对于给定的容器类型。我还根据您的请求删除了auto
,并切换到const&
传递容器以避免复制:
int GetID(const pair<int, Player*>& item) {
return item.second->_id;
}
int GetID(Player* item) {
return item->_id;
}
template <class ContType>
bool isSameID(const ContType& cont, int id) {
typename ContType::const_iterator found = find_if(begin(cont), end(cont),
[id] (typename ContType::value_type item) {
return GetID(item) == id;
});
return found != end(cont);
}
答案 2 :(得分:0)
你的封装有问题,因为函数不知道DataStruct是什么,它不能直接取消引用它的内部迭代器。 如果为迭代器实现一个去引用运算符,它将起作用。
在迭代器中添加:
objStored *operator(){
return **this;
}
然后在你的玩家obj中添加一个获取id的方法:
int getId(){
return this->id;
}
而不是(*player)->_id == id
写(*player)->getId()
这样任何在迭代器中拥有(以任何方式)支持(以任何方式)getId方法的对象的类都可以工作。
如果你使用模板创建一个通用函数,你就不应该这样做它只适用于一个具有迭代器的类,该迭代器是指向具有_id成员的玩家的指针。 尽量少考虑你的物品。