基本クラスと派生クラスへの共有ポインタをとるオーバーロードされた関数を作成します。これは参照と生ポインタのために働くようですが、余分な派生クラスの場合は共有ポインタのためには機能しません。私が手共有ポインタの引数のあいまいさによる関数のオーバーロード
#include <memory>
class Base{};
class Derived : public Base {};
class ExtraDerived : public Derived {};
bool IsBase(Base*){ return true; }
bool IsBase(Derived*){ return false; }
bool IsBase(std::shared_ptr<Base>){ return true; }
bool IsBase(std::shared_ptr<Derived>){ return false; }
int main()
{
auto derived = std::make_shared<Derived>();
auto extra_derived = std::make_shared<ExtraDerived>();
// works
auto raw_result_derived = IsBase(derived.get());
auto raw_result_extra_derived = IsBase(extra_derived.get());
auto shared_result_derived = IsBase(derived);
// doesn't work
auto shared_result_extra_derived = IsBase(extra_derived);
}
:「エラーC2668: 『IsBase』:オーバーロードされた関数のあいまいな呼び出しを」コード例を参照してくださいのVisual Studio 2012を使用しているとき、私はここにhttp://ideone.com/6uoa0p上でコードをしようとすると、私も同じ結果を得ます。
これは望ましい動作のようには見えません( '生のもの'の場合)。これはテンプレートの制限ですか、これがうまくいかない理由があるのでしょうか、バグですか? そして、どうやって少なくとも醜い方法で動作させることができますか?
私が思い付くことができる最高は
//ugly workaround
bool IsBase(std::shared_ptr<Base>, Base*){ return true; }
bool IsBase(std::shared_ptr<Derived>, Derived*){ return false; }
template<typename T> bool IsBase(std::shared_ptr<T> input)
{
return IsBase(input, input.get());
}
あなたがそれを望むのはなぜ?基本関数のみを提供するだけで、派生クラスポインタをうまく受け入れることができます。派生クラスオブジェクトを捕捉したい場合は、関数の引数の動的型をディスパッチする必要があるため、メソッドはうまく動作しません。プログラマが渡す前に 'Ptr'を 'Ptr 'に暗黙的に変換すると、このオーバーロードの手法は壊れてしまいます。 –
@ JohannesSchaub-litb私はそのような状況は考えていませんでした。私は自分が望むものを考え直さなければならないかもしれない。 – Barabas