问题描述
我有以下课程:
public:
Client(tcp::socket socket)
: socket_(std::move(socket))
{
}
void start();
int connectionId;
比我有以下向量:
class Server {
public:
Server();
static std::vector<std::shared_ptr<Client>> Clients;
}
编辑*
我可以做这样的事情吗?
for (int i = 0; i < Server::Clients.size(); ++i) {
if(Server::Clients[i]->connectionId == connectionId)
Server::Clients.erase(Server::Clients.begin()+i);
}
我的问题是如何才能将Clients
中的共享指针与特定的connectionId
一起按值删除?
解决方法
在C ++ 17中,您可以使用std::remove_if
。以下应该起作用。
#include <algorithm>
Server &s = /* <getServerFromSomewhere> */;
auto new_end = remove_if(s.Clients.begin(),s.Clients.end(),[] (std::shared_ptr<Client>& p) {
return p->connectionId == /* <someValueToBeRemoved> */;
}
);
s.Clients.resize(new_end - s.Clients.begin());
,
使用std::remove_if
和lambda作为谓词,然后使用容器的方法erase
:
std::vector<std::shared_ptr<Client>> Clients;
int id{0}; // the id to be removed
Clients.erase(std::remove_if(Clients.begin(),Clients.end(),[id](const auto &entity) { return id == entity->connectionId; }),Clients.end());
,
如果您无权访问std::remove_if
,则必须退回到某种循环:
auto it = Clients.begin()
while (it != Clients.end())
{
if((*it)->connectionId = testValue)
{
// can connection id be non-unique?
it = Clients.erase(it);
//if yes,we have to save new iterator
continue;
}
it++;
}
如果connectionId
是唯一的,请使用find_if来查找该元素并将其删除,这样会更便宜。
如果remove_if
可用,则以下代码是可行的,如果它比第一个示例的优势值得商。
auto new_end = remove_if(s.Clients.begin(),[=] (auto& ptr) {
return ptr->connectionId == testValue; /* value to be removed */
}
erase(new_end,Clients.end()); // remove tail of vector that is now consisting of empty elements.
Clients
最好是deque
,而不是向量,那样从其中擦除元素不会导致每次删除都复制Clients
列表的“ tail”部分完成。