2013-03-08 72 views
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>,其中T是一個對象。我總是會用vector<shared_ptr<T>>。如果T是一個像int這樣的基本類型,我猜它有點直接使用vector<T>

我認爲這個例子,因爲我認爲這是很一般的,你總要拉一些數據從數據庫或XML文件或任何其他來源。你會在你的數據訪問層有vector<T>還是vector<shared_ptr<T>>

+2

老實說,我會用'的std :: back_inserter(搜查)'的'copy_if'的輸出迭代器,並完全放棄初始大小。 – WhozCraig 2013-03-08 21:18:54

+1

對於大多數情況(特別是#2)而言,一個好的迴應歸結於您爲什麼要首先製作副本的問題。如果可能,儘量避免進行復制,並使用類似'transform_if'的東西來過濾*和處理子集,而不是僅創建和存儲子集。 – 2013-03-08 21:32:59

回答

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

Concering你的第二個問題:

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(除了複製和移動這些對象的可能的性能考慮事項外)。根據您提供的信息,目前尚不清楚是否屬於這種情況,所以它可能會或可能不是個好主意。

+0

+1 = P betcha沒有看到*即將到來。 – WhozCraig 2013-03-08 21:19:51

+0

@WhozCraig :-) – 2013-03-08 21:21:09

+0

我錯過了那個back_inserter。 1)解決了。那麼2)呢? – 2013-03-08 21:22:30

0

你打算怎麼處理所有這些學生?

只是做到這一點,而不是:

for(Student& student: students) { 
    if(student.firstNameMatches("an")) { 
     //.. do something 
    } 
} 
相關問題