cpp*_*lex 6 c++ templates overloading function
如何强制编译器为基类选择模板函数重载?
这是一个说明问题的例子
#include <iostream>
class A
{};
class B : public A
{};
template <class T>
void f (const T& t)
{
std::cout << "Generic f" << std::endl;
}
void f (const A& a)
{
std::cout << "Overload for A" << std::endl;
}
template <class T>
void call_f (const T& t)
{
f (t);
}
int main()
{
call_f (10);
call_f (A());
call_f (B());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它产生输出
Generic f
Overload for A
Generic f
Run Code Online (Sandbox Code Playgroud)
为什么编译器f (const A&)在第三种情况下没有接收?UPD:好的,这个比一个void f<B> (const B&)好void f (const A&),但我还在寻找第二个问题的答案.
是否有可能强制它这样做而不将B铸成A?
使用call_f(B())结果调用与模板版本最匹配的“f()”。对于非模板版本需要进行转换。结果,选择了模板。如果模板和非模板都是同样好的选择,那么非模板将是首选。
如果您想调用非模板,则需要将模板设置为非选项。例如,模板可以像这样实现
#include <type_traits>
template <class T>
typename std::enable_if<!std::is_base_of<A, T>::value>::type f(T const&)
{
std::cout << "Generic f\n";
}
Run Code Online (Sandbox Code Playgroud)
如果无法使用 C++11,您可以实现 的版本、使用Booststd::is_base_of<...>的版本或使用简单的调度:
struct true_type {};
struct false_type {};
true_type A_is_base_of(A const*) { return true_type(); }
false_type A_is_base_of(void const*) { return false_type(); }
template <class T>
void f (T const&, false_type)
{
std::cout << "Generic f\n";
}
void f (A const&, true_type)
{
std::cout << "Overload for A\n";
}
template <class T>
void call_f (const T& t)
{
f (t, A_is_base_of(&t));
}
Run Code Online (Sandbox Code Playgroud)