我想制作重载函数,这些函数采用指向基类和派生类的共享指针。它似乎适用于引用和原始指针,但不适用于额外派生类的共享指针。请参阅示例代码:
#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);
}
使用 Visual Studio 2012 时,我得到:“错误 C2668:'IsBase':对重载函数的模糊调用”,但当我在这里尝试代码时,我也得到了相同的结果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());
}