Nik*_*ond 5 c++ overload-resolution
我有两节课:
class Base {};
class Derived : public Base {};
Run Code Online (Sandbox Code Playgroud)
还有两个重载函数:
void call(std::unique_ptr<Base> op)
{
std::cout << "First overloading" << std::endl;
}
template<class F>
void call(F f)
{
std::cout << "Second overloading" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
用Derived的unique_ptr来称呼它
call(std::make_unique<Derived>());
Run Code Online (Sandbox Code Playgroud)
我希望调用第一个函数,但是调用第二个函数。为什么编译器选择通用函数而不是特定函数?重载解析不支持继承和多态吗?如果是这样,我该如何修复它并调用第一个函数?
您的两个重载都是有效的候选者。如果删除其中任何一个,则其余的仍然是有效的重载。从广义上讲,在这种情况下,将选择的重载将与提供的参数最接近。
您提供了std::unique_ptr<Derived>。在第一种情况下,它期望std::unique_ptr<Base>。存在从std::unique_ptr<Derived>到的隐式转换std::unique_ptr<Base>,因此此重载是合法的,但确实需要进行转换。
在第二种情况下,F简单推导为std::unique_ptr<Derived>。它不需要转换,并且与提供的参数更匹配。因此,这是优选的。
编辑:似乎我错过了有关修复的部分。
您可以unique_ptr改为使重载接受功能模板。这样,您可以与第一个重载完全匹配,而无需进行转换。您可以使用std::enable_if禁用unique_ptr不兼容类型的s 重载:
#include <memory>
#include <type_traits>
class Base {};
class Derived : public Base {};
template<class T>
std::enable_if_t<std::is_base_of<Base, T>::value>>
call(std::unique_ptr<T>);
template<class T>
void call(T);
Run Code Online (Sandbox Code Playgroud)