如何从源向量<>构建搜索结果的向量<>?

Jac*_*son 4 c++ c++11

考虑这个例子:

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));
Run Code Online (Sandbox Code Playgroud)

我有以下问题:

  1. 为搜索到的向量等于初始向量分配内存是否可以?可能有500个不小的对象,也许没有一个满足搜索条件?还有其他方法吗?
  2. 当复制到搜索到的矢量时,它被称为复制赋值操作符,并且......显然是复制.如果满足搜索条件的500个对象400怎么办?不只是记忆浪费?

我是一个c ++ noob所以我可能会说一些愚蠢的话.我不明白为什么要永远使用vector<T>其中T的一个对象.我总是会用vector<shared_ptr<T>>.如果T是像int这样的原始类型,我猜它有点直接使用vector<T>.

我考虑过这个例子,因为我觉得它很通用,你总是需要从数据库或xml文件或任何其他来源中提取一些数据.你有没有vector<T>在你的数据访问层或vector<shared_ptr<T>>

And*_*owl 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; 
        });
}
Run Code Online (Sandbox Code Playgroud)

再想一下你的第二个问题:

2 - 当复制到搜索到的矢量时,它被称为复制赋值操作符,并且......显然是复制.如果满足搜索条件的500个对象400怎么办?不只是记忆浪费?

好吧,如果你没有关于谓词选择性的统计信息,那么你就无法做到这一点.当然,如果您的目的是以某种方式处理某个谓词为真的所有学生,那么您应该使用std::for_each()源向量而不是创建单独的向量:

std::for_each(students.begin(), students.end(), [] (const Student &stud) 
{ 
    if (stud.getFirstName().find("an") != std::string::npos)
    {
        // ...
    }
});
Run Code Online (Sandbox Code Playgroud)

但是,这种方法是否满足您的要求取决于您的特定应用.

我不明白为什么要永远使用vector<T>其中T的一个对象.我总是会用vector<shared_ptr<T>>.

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

  • @JackWillson#2完全取决于您是否希望保持原始容器的结果的独立性以进行修改目的如果您需要它们进行修改,而不是*希望传播到原始容器中的对象,则共享指针不是一个好的举动.如果你可以修改开始反映在两个向量中,或者你根本没有计划修改它们,那么如果内存占用是一个问题,共享指针是值得考虑的.*但首先要确保它是一个问题**.*除非你知道它有问题,否则不要过度优化. (2认同)