0

我环顾四周,并没有找到我要找的东西。基本上我想要一个由基类专门化的函数模板。我不知道如何使它使用专门的功能。

意义...

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是抽象的。

4

2 回答 2

1

只需使用重载函数即可。

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

重载的函数总是在模板之前被选中。

于 2014-02-04T22:26:55.127 回答
0

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

有问题的代码不起作用的主要原因是目前,类型推导和转换不能很好地相互配合。您需要转换&b为专用函数所期望的指向其父类(即 IBase*)的指针类型。由于当前C++存在这个问题,有必要通过使用来帮助编译器。

get_func((const IBase*)&b);

其次,添加virtual

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

,因为 IBase::func 被定义为一个虚成员函数。(这对于所有编译器都不是必需的:派生类中函数的 C++“虚拟”关键字。有必要吗?)。

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

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; // 
}
于 2014-02-04T22:24:02.127 回答