4

考虑这个例子:

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));

我有以下问题:

  1. 是否可以为搜索到的向量分配内存等于初始向量?可能有 500 个不小的对象,可能没有一个满足搜索条件?还有其他方法吗?
  2. 当复制到搜索到的向量时,它被称为复制赋值运算符,并且..显然会进行复制。如果从这 500 个对象中 400 个满足搜索条件呢?不只是浪费内存吗?

我是一个 C++ 菜鸟,所以我可能会说一些愚蠢的话。我不明白为什么要使用vector<T>whereT是一个对象。我会一直使用vector<shared_ptr<T>>. IfT是像 int 这样的原始类型,我想它使用起来有点简单vector<T>

我考虑了这个示例,因为我认为它非常笼统,您总是必须从数据库或 xml 文件或任何其他来源中提取一些数据。您是否曾经vector<T>在数据访问层中使用过vector<shared_ptr<T>>

4

2 回答 2

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>whereT是一个对象。我会一直使用vector<shared_ptr<T>>.

是否使用(智能)指针而不是值取决于您是否需要引用语义(除了可能的关于复制和移动这些对象的性能考虑)。根据您提供的信息,尚不清楚是否是这种情况,因此这可能是一个好主意,也可能不是一个好主意。

于 2013-03-08T21:19:05.500 回答
0

你打算怎么处理所有这些学生?

只需这样做:

for(Student& student: students) {
    if(student.firstNameMatches("an")) {
        //.. do something
    }
}
于 2013-03-08T21:44:45.237 回答