使用基类的函数模板专业化

时间:2014-02-04 21:03:59

标签: c++ templates template-specialization function-templates

我环顾四周,找不到我正在寻找的东西。基本上我想要一个基类专用的函数模板。我不知道如何使用专门的功能。

...含义

class IBase
{
public:
    virtual std::string func() const = 0;
};

class MyClass : public IBase
{
public:
    std::string func() const { return "From MyClass"; }
};

template <class T>
std::string get_func(const T* t)
{
    return "Unknown";
}

template <>
std::string get_func<IBase>(const IBase* t)
{
    return t->func();
}

int main()
{
    int a;
    MyClass b;

    get_func(&a); // <- Returns 'Unknown'. Good.
    get_func(&b); // <- Returns 'Unknown'. Bad, want 'From MyClass'.
}

我使用const T*的原因是因为IBase是抽象的。

2 个答案:

答案 0 :(得分:1)

只需使用重载功能。

std::string get_func(const IBase *t) {
    return t->func();
}

在模板之前始终选择重载函数。

答案 1 :(得分:0)

在接受的答案中使用函数重载来替换函数模板特化并不总是一个好主意。对于问题中的示例代码,函数重载不能提供默认实现,该实现为非专用类打印“未知”。函数重载不足的其他示例包括元组和几乎任何可变参数编程。

有问题的代码不起作用的主要原因是,目前,类型演绎和转换不能很好地相互配合。您需要将&b转换为其父类(即IBase *)的指针类型(专用函数所期望的)。由于当前C ++中的这个问题,有必要使用。

来帮助编译器
get_func((const IBase*)&b);

其次,将virtual添加到

可能更好
std::string func() const { return "From MyClass"; } 

,因为IBase :: func被定义为虚拟成员函数。 (这对于所有编译器都不是必需的:C++ "virtual" keyword for functions in derived classes. Is it necessary?)。

通过这些更改,下面的代码输出了预期的内容:

Unknown
From MyClass

代码:

#include <string>
#include <iostream>
using namespace std;

class IBase
{
public:
    virtual std::string func() const = 0;
};

class MyClass : public IBase
{
public:
    virtual std::string func() const { return "From MyClass"; }
};

template <class T>
std::string get_func(const T* t)
{
    return "Unknown";
}

template <>
std::string get_func<IBase>(const IBase* t)
{
    return t->func();
}

int main()
{
    int a;
    MyClass b;

    cout << get_func(&a) << endl; // <- Returns 'Unknown'. Good.
    cout << get_func((const IBase*)&b) << endl; // 
}