4

共有ポインタのコンテナに基づく次のクラスを考えると、

class Foo;

class Bar {
public:
  // ...
  const std::vector<boost::shared_ptr<const Foo> >& getFoos() const { return foos_; }
private:
  std::vector<boost::shared_ptr<Foo> > foos_;
};

コンパイルされません

invalid initialization of reference of type ‘const std::vector<boost::shared_ptr<const Foo>, std::allocator<boost::shared_ptr<const Foo> > >&’ from expression of type ‘const std::vector<boost::shared_ptr<Foo>, std::allocator<boost::shared_ptr<Foo> > >’

メンバーは、オブジェクトが内部で使用するためfoos_に可変オブジェクトを指す必要がありますが、クライアントコード呼び出しで何かを変更できるようにしたくありません。FooBargetFoos()

constリターンタイプから修飾子を削除するFooと、getFoos()これが修正されます。しかし、私は、std::vectorその恒常性をその要素に伝播する一方boost::shared_ptrで、それが指すオブジェクトにはそのようなことを(当然のことながら)行わないことを理解しています。したがって、クライアントコードは、返された共有ポインターが指すオブジェクトを変更できるため、(コンパイラーが文句を言わなくても)修飾子getFoos()を監視しなくなったように見えます。constFoo

私は正しいですか?getFoos()もしそうなら、コピーせずにconstオブジェクトへのconst参照のconstベクトルを返すように書く方法はありますか?

4

3 に答える 3

3

私は間違っているかもしれませんが、あなたがこれを達成できるとは本当に思いません。

shared_ptr<Foo>shared_ptr<const Foo>新しいインスタンスを構築することによってのみになることができますshared_ptr<const Foo>

への参照を への参照にするshared_ptr<Foo>ことはできません。shared_ptr<const Foo>単純に、それらは 2 つの異なる型だからです。

ここでは、 への参照をvector<shared_ptr<Foo>>の形式に取得しようとしていconst vector<shared_ptr<const Foo>>ます。

最初constはまったく問題ありません。const 修飾子を使用して同じ参照型に参照を割り当てても問題ないためです。

しかし、2 番目constはそうではありません。文字どおり のベクトルType Aへの参照を のベクトルへの参照に変換しようとしているからですType B

于 2012-11-19T23:36:08.083 に答える
2

を返す代わりにstd::vector<...> const&、範囲を返すのはどうですか? 範囲は、pairある種の反復子の です。この場合、イテレータは to になりますstd::shared_ptr<const foo>。これを行うには、内部的に を反復処理するクイック イテレータ アダプタを作成しconst_iteratorますstd::shared_ptr<foo>が、それらを として返しますstd::shared_ptr<const foo>

で実行したいほとんどの操作は、の ランダム アクセス でconst vector実行できます。rangeconst_iterator

于 2012-11-20T18:14:51.957 に答える
0

ベクトルの代わりにポインターを返すことができconst shared_ptr<Foo>*、明示的な醜い C スタイルのキャストを使用foos_.data()して、必要なものに変換できます。

const ベクトルを返すことに関心があるので、サイズ情報を除いて、ポインターを返すことによって多くを失うことはありません。作成時に提供されるこのサイズ情報を提供するように設計されたクラスで、新しいポインターをいつでもラップできます。

于 2012-11-20T00:00:23.827 に答える