我想製作帶有共享指針的基類和派生類的重載函數。它似乎適用於引用和原始指針,但不適用於額外派生類情況下的共享指針。使用Visual Studio 2012的時候,但我也得到相同的結果時,我嘗試在這裏http://ideone.com/6uoa0p代碼查看示例代碼:帶共享指針參數歧義的函數重載
#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’」 。
這看起來不像想要的行爲(因爲它適用於'生''東西)。這是模板的一個限制,是否有另一個原因爲什麼這不起作用或者它是一個錯誤? 我怎樣才能以最醜陋的方式工作?
我能想出的最好的是
//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