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

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番目の質問について:

2 - 検索されたベクトルにコピーするとき、それはコピー代入演算子と呼ばれ、..明らかにコピーが作成されます。これらの 500 個のオブジェクトのうち 400 個が検索基準を満たす場合はどうなるでしょうか? メモリが無駄になっていませんか?

述語の選択性に関する統計情報がない場合、それについてできることはあまりありません。もちろん、特定の述語が true であるすべての学生を何らかの方法で処理することが目的である場合はstd::for_each()、別のベクトルを作成するのではなく、ソース ベクトルで使用する必要があります。

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

ただし、このアプローチが要件を満たすかどうかは、特定のアプリケーションによって異なります。

vector<T>where Tis a objectを使用する理由がわかりません。私はいつも使用します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 に答える