基类的模板函数重载 [英] Template function overload for base class

查看:417
本文介绍了基类的模板函数重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何强制编译器为基类拾取模板函数重载?



下面是一个说明问题的示例

  #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< 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;
}

它产生输出

 通用f 
A
的重载通用f


b $ b

为什么在第三种情况下编译器不能拾取 f(const A&) UPD :好的,这个很清楚 void f< B> (const B&) void f(const A&)好,但我仍然在寻找第二个问题的答案。 / p>

是否可以强制它不将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 \\\
;
}

如果不能使用C ++ 11, std :: is_base_of< ...> ,请使用 Boost 或使用简单的分派:

  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 \\\
;
}

void f(A const& true_type)
{
std :: cout< Overload for A\\\
;
}

template< class T>
void call_f(const T& t)
{
f(t,A_is_base_of(& t));
}


How do I force compiler to pick up a template function overload for a base class?

Here is an example that illustrates the question

#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;
}

It produces the output

Generic f
Overload for A
Generic f

Why doesn't the compiler pick up f (const A&) in the 3rd case? UPD: OK, this one is clear void f<B> (const B&) is better than void f (const A&), but I'm still looking for answer to the 2nd question.

And is it possible to force it to do so without casting B to A?

解决方案

Using call_f(B()) results in a call to `f() which is best matched by the template version. For the non-template version a conversion is required. As a result, the template is chosen. If the template and the non-template would be equally good options, the non-template would be preferred.

If you want to the non-template to be called, you'll need to make the template a non-option. for example, the template could be implemented like

#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";
}

If C++11 can't be used you could either implement a version of std::is_base_of<...>, use a version from Boost or use a simple dispatch:

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));  
}

这篇关于基类的模板函数重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆