2017-02-27 16 views
2

と仮定我々は、以下の機能を持っている:ベクトル<shared_ptr <T>>を定数ベクトル<shared_ptr <const T>>とパラメータに渡すことはできますか?

void doStuff(const std::vector<std::shared_ptr<const Foo>>& fs) { } 

は(安全に)このパラメータにstd::vector<std::shared_ptr<Foo>>を渡す方法はありますか?たとえば:

std::vector<std::shared_ptr<Foo>> foos; 
doStuff(foos); 

この暗黙の変換は失敗しますが、キャストで安全に実行できますか? (これは理論的には安全であると思われます。関数はベクターやその内部のオブジェクトを変更できないためです)

+0

constアイテムのshared_ptrを作成すると、複雑さが増すことがわかります。しかし、私はあなたがハックなしでこれを行うことができるとは思わない。 –

+0

これは明確に未定義の動作です。それは毎回動くはずですが、それに頼ることはできません。未定義の動作を示すコードを削除することを含め、コンパイラがどのような変換を行う可能性があるかは誰に分かりますか。 –

+0

未定義の動作とは何ですか?私の質問のコードはコンパイルされないので、おそらくあなたはいくつかの仮説 'const_cast'を参照していますか? – jtbandes

答えて

2

短い答えは "いいえ"です。クラステンプレート

template <typename T> struct Foo {}; 

Foo<int>Foo<const int>考える

は、二つの異なる種類があります。この2つのタイプ間の暗黙の変換はありません。

doStuffを機能テンプレートにすることをお勧めします。

template <typename T> 
void doStuff(const std::vector<T>& fs) { } 

または

template <typename T> 
void doStuff(const std::vector<std::shared_ptr<T>>& fs) { } 

あなたがdoStuffを変更するオプションがない場合は、shared_ptr<Foo>ためdoStuffからコードを複製することは、おそらく行う唯一のまともなものです。

+0

暗黙的な変換は機能しませんが、ここで明示的なキャストを安全に使用する方法があるかどうかを確認しています。 – jtbandes

+0

を回避するには、 'std :: transform'(http://en.cppreference.com/w/cpp/algorithm/transform)を調べて、一度に1つの項目を取り出してdoSomethingに変更して適切なタイプ。 – moka

0

いいえ、代わりにできるのは、インターフェースをより包括的に変更することです。

void doStuff(std::vector<std::shared_ptr<Foo const>> const& fs) { } 

をしかし、あなたが本当にしたいことはstd::shared_ptr<const Foo>右のほんのいくつかの連続した範囲である:あなたが書くのか?それではにそれを変更してみましょう:

void doStuff(gsl::span<std::shared_ptr<Foo const>> fs) { } 

しかし、その後、本当に、私たちは、自身がconstを指すように、共有のポインタが必要なのでしょうか、それは彼らがconstあることは十分ありますか?

void doStuff(gsl::span<std::shared_ptr<Foo> const> fs) { } 

これで、​​で呼び出すことのできるインターフェイスが用意されました。

関連する問題