考虑这个例子:
std::vector<Student> students;
//poplate students from a data source
std::vector<Student> searched(students.size());
auto s = std::copy_if(students.begin(), students.end(), searched.begin(),
[](const Student &stud) {
return stud.getFirstName().find("an") != std::string::npos;
});
searched.resize(std::distance(searched.begin(), s));
我有以下问题:
我是一个c ++菜鸟,所以我可能会说些蠢话。我不明白为什么要使用vector<T>
T
作为对象。我会一直使用vector<shared_ptr<T>>
。如果T
是一个类似int的基本类型,我猜它有点直接使用vector<T>
。
我考虑过这个例子,因为我觉得它很通用,你总是需要从数据库或xml文件或任何其他来源中提取一些数据。您是否曾在数据访问层或vector<T>
中使用vector<shared_ptr<T>>
?
答案 0 :(得分:8)
关于你的第一个问题:
1 - 为搜索到的向量等于初始向量分配内存是否可以?可能有500个不小的对象,也许没有一个满足搜索条件?还有其他办法吗?
您可以使用后插入器迭代器,使用std::back_inserter()
标准函数为searched
向量创建一个:
#include <vector>
#include <string>
#include <algorithm>
#include <iterator> // This is the header to include for std::back_inserter()
// Just a dummy definition of your Student class,
// to make this example compile...
struct Student
{
std::string getFirstName() const { return "hello"; }
};
int main()
{
std::vector<Student> students;
std::vector<Student> searched;
// ^^^^^^^^^
// Watch out: no parentheses here, or you will be
// declaring a function accepting no arguments and
// returning a std::vector<Student>
auto s = std::copy_if(
students.begin(),
students.end(),
std::back_inserter(searched),
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Returns an insert iterator
[] (const Student &stud)
{
return stud.getFirstName().find("an") != std::string::npos;
});
}
再想一下你的第二个问题:
2 - 当复制到搜索到的矢量时,它被称为复制赋值操作符,并且......显然会复制。如果满足搜索条件的500个对象400怎么办?难道只是记忆浪费吗?
好吧,如果你没有关于谓词选择性的统计信息,那么你就无法做到这一点。当然,如果您的目的是以某种方式处理某个谓词为真的所有学生,那么您应该在源向量上使用std::for_each()
而不是创建单独的向量:
std::for_each(students.begin(), students.end(), [] (const Student &stud)
{
if (stud.getFirstName().find("an") != std::string::npos)
{
// ...
}
});
但是,这种方法是否满足您的要求取决于您的具体应用。
我不明白为什么要使用
vector<T>
T
作为对象。我会一直使用vector<shared_ptr<T>>
。
是否使用(智能)指针而不是值取决于whether or not you need reference semantics(除了关于复制和移动这些对象的可能的性能考虑因素)。根据您提供的信息,目前尚不清楚是否属于这种情况,因此它可能是也可能不是一个好主意。
答案 1 :(得分:0)
你打算和那些学生一起做什么?
请改为:
for(Student& student: students) {
if(student.firstNameMatches("an")) {
//.. do something
}
}