0

次のようなクラスFooがあるとします。

class Foo {
public:
    std::vector<Bar> barVec() const {return barVec_;}

private:
    std::vector<Bar> barVec_;
};

ここで、Barは他のクラスです。したがって、Fooの外部では、barVec_への唯一のアクセスはメソッドbarVec()を介して行われます。

myFooがFooのインスタンスであり、predがBarの単項述語である場合、次のようなことをしても大丈夫ですか。

auto i = find_if(myFoo.barVec().begin(), myFoo.barVec().end(), pred);
if (i != myFoo.barVec().end()) {
    //do some stuff here
}

または、myFoo.barVec()を変数に割り当てて、その変数を反復処理する必要がありますか?例えば:

std::vector<Bar> tmp = myFoo.barVec();
auto i = find_if(tmp.begin(), tmp.end, pred);
if (i != tmp.end()) {
    //do some stuff here
}
4

3 に答える 3

6

いいえ、ベクトルを返すときにベクトルのコピーを作成するため、比較しているイテレータが異なるコンテナを参照するため、これは未定義の動作であるため、OKではありません。

(-)参照を返すこともできますが、ベクトルを公開するよりも、オーバーロードしてクラスを適切にする方がconstはるかにクリーンです。beginend

于 2013-03-18T19:08:14.400 に答える
1

myBar私はあるべきでmyFooあり、タイプであると仮定しFooます。

std::vector<Bar>最初にオブジェクトに割り当てる必要があります。問題は、myFoo.barVec()内に格納されているベクトルのコピーを返すことmyFooです。行内のへの呼び出しごとに、異なる一時オブジェクトが返さbarVecれます。これらの2つの一時オブジェクトのおよびイテレータは、同じシーケンスには適用されません。これは、未定義の動作があることを意味します。find_ifstd::vector<Bar>beginend

于 2013-03-18T19:07:52.977 に答える
1

Foo::barVec()呼び出すたびにベクトルのコピーを返します。したがって、イテレータは、異なるオブジェクトへの2回の呼び出しによって返され、異なるオブジェクトFoo::barVec().begin()Foo::barVec().end()属します。

あなたはおそらく参照を返すつもりでした:

const std::vector<Bar>& barVec() const {return barVec_;}

ただし、基になるベクターデータメンバーを公開するのではなく、クラスから直接begin()およびイテレータを返すメソッドを提供することを検討する必要があります。end()

于 2013-03-18T19:09:23.853 に答える