我需要能够从向量中删除元素,并决定研究擦除-删除习惯用法,这是一种来自c++标准库的算法,比手工编写的循环更可取。我还想使用智能指针的向量,而不是原始指针。
我发现了很多关于擦除习语的帖子,其中相当一部分实际上建议使用智能指针。按照这个建议,我写了3个可行的擦除习语的例子,我复制在下面的输出前面:无指针,原始指针和智能指针。注意智能指针所需的三重解引用。
我的问题:这是一个很好的实现擦除-删除习语与智能指针或有一些…聪明吗?谢谢你的关心。
int向量:1 1 3
Vector of int: 3
int型智能指针的向量:1 1 3
int型智能指针的向量:1 3
#include <windows.h>
#include <algorithm>
#include <iostream>
#include <vector>
#include <memory>
#include <string>
std::vector<int> intVector;
std::vector<int*> intVectorPointers;
std::vector<std::shared_ptr<int*>> intVectorSmartPointers;
void printVector(std::vector<int> intV){
std::cout << "vector of int: ";
for (std::vector<int>::const_iterator it = intV.begin(); it != intV.end(); it++)
std::cout << ' ' << *it;
std::cout << 'n';
}
void printVectorPointers(std::vector<int*> intVPointers){
std::cout << "vector of pointers of int: ";
for (std::vector<int*>::const_iterator it = intVPointers.begin(); it != intVPointers.end(); it++)
std::cout << ' ' << **it;
std::cout << 'n';
}
void printVectorSmartPointers(std::vector<std::shared_ptr<int*>> intVSmartPointers) {
std::cout << "vector of smart pointers of int: ";
for (std::vector<std::shared_ptr<int*>>::const_iterator it = intVSmartPointers.begin(); it != intVSmartPointers.end(); it++)
std::cout << ' ' << ***it;
std::cout << 'n';
}
int main(int argc, char* argv[]) {
int int1 = 1;
int int2 = 1;
int int3 = 3;
int *intPointer1 = &int1;
int *intPointer2 = &int2;
int *intPointer3 = &int3;
std::shared_ptr<int*> intSmartPointer1 = std::make_shared<int*>(intPointer1);
std::shared_ptr<int*> intSmartPointer2 = std::make_shared<int*>(intPointer2);
std::shared_ptr<int*> intSmartPointer3 = std::make_shared<int*>(intPointer3);
intVector.push_back(int1);
intVector.push_back(int2);
intVector.push_back(int3);
intVectorPointers.push_back(intPointer1);
intVectorPointers.push_back(intPointer2);
intVectorPointers.push_back(intPointer3);
intVectorSmartPointers.push_back(intSmartPointer1);
intVectorSmartPointers.push_back(intSmartPointer2);
intVectorSmartPointers.push_back(intSmartPointer3);
printVector(intVector);
intVector.erase(std::remove(intVector.begin(), intVector.end(), int1), intVector.end());
printVector(intVector);
printVectorPointers(intVectorPointers);
intVectorPointers.erase(std::remove(intVectorPointers.begin(), intVectorPointers.end(), intPointer1), intVectorPointers.end());
printVectorPointers(intVectorPointers);
printVectorSmartPointers(intVectorSmartPointers);
intVectorSmartPointers.erase(std::remove(intVectorSmartPointers.begin(), intVectorSmartPointers.end(), intSmartPointer1), intVectorSmartPointers.end());
printVectorSmartPointers(intVectorSmartPointers);;
Sleep(50000);
return 0;
}
正如其他人指出的那样,除了删除本身之外,代码还有其他问题。
然而,std::remove_if()
失败的原因是因为您搜索intPointer1并删除了一个1指针,而不是指向数字1的指针。
你没有说你是否可以访问c++ 11或更好的版本,希望你可以。您可以编写一个lambda来实现:
intVectorPointers.erase(
std::remove_if(
intVectorPointers.begin(),
intVectorPointers.end(),
[](auto const & p) { return *p == 1; }),
intVectorPointers.end());
我没有测试过你的整个代码,但类似的东西应该工作。(这是假设你修复你的指针和*p实际上指向数据,而不是另一个指针,在你的例子中,我很确定这不是你想要的。)
所以它可以帮助其他人,下面是一个带有智能指针的擦除-删除习语的干净版本。关于你的评论,不再有指针的指针,唯一指针而不是共享指针,remove_if()
而不是remove()
。
#include <windows.h>
#include <algorithm>
#include <iostream>
#include <vector>
#include <memory>
void printVectorSmartPointers(std::vector<std::unique_ptr<int>> &vSmartPointers) {
std::cout << "vector of smart pointers of int: ";
for (std::vector<std::unique_ptr<int>>::const_iterator it = vSmartPointers.begin(); it != vSmartPointers.end(); it++)
std::cout << ' ' << **it;
std::cout << 'n';
}
int main(int argc, char* argv[]) {
std::unique_ptr<int> smartPointer1 = std::make_unique<int>(1);
std::unique_ptr<int> smartPointer2 = std::make_unique<int>(1);
std::unique_ptr<int> smartPointer3 = std::make_unique<int>(3);
std::vector<std::unique_ptr<int>> vectorSmartPointers;
vectorSmartPointers.push_back(std::move(smartPointer1));
vectorSmartPointers.push_back(std::move(smartPointer2));
vectorSmartPointers.push_back(std::move(smartPointer3));
printVectorSmartPointers(vectorSmartPointers);
vectorSmartPointers.erase(
std::remove_if(
vectorSmartPointers.begin(),
vectorSmartPointers.end(),
[](std::unique_ptr<int> const &p) { return *p == 1; }),
vectorSmartPointers.end());
printVectorSmartPointers(vectorSmartPointers);
Sleep(50000);
return 0;
}