简体   繁体   English

使用基类的功能模板专门化

[英]Function Template Specialization using Base Class

I've looked around and not found quite what I'm looking for. 我环顾四周,但找不到我想要的东西。 Basically I want a function template specialized by a base class. 基本上,我想要一个由基类专用的功能模板。 I don't know how to make it use the specialized function. 我不知道如何使用专门功能。

Meaning... 含义...

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'.
}

The reason I use const T* is because IBase is abstract. 我使用const T*的原因是因为IBase是抽象的。

Just use an overloaded function instead. 只需使用重载函数即可。

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

Overloaded functions are always selected before templates. 总是在模板之前选择重载的功能。

Using function overloads in the accepted answer to replace function template specialization isn't always a good idea. 在公认的答案中使用函数重载来替换函数模板特化并不总是一个好主意。 For the example code in the question, function overloading cannot provide a default implementation which prints "Unknown" for non-specialized classes. 对于问题中的示例代码,函数重载不能提供默认的实现,该默认实现为非专业类打印“ Unknown”。 Other examples where function overloading is insufficient include tuples and virtually any variadic programming. 函数重载不足的其他示例包括元组和几乎任何可变参数编程。

The primary reason why the code in question doesn't work is that currently, type deduction and conversion do not play nicely with each other. 所讨论的代码无法正常工作的主要原因是,目前,类型推导和转换不能很好地配合使用。 You need to cast &b to a pointer type to its parent class (ie IBase*) which the specialized function expects. 您需要将&b强制转换为专用函数期望的其父类(即IBase *)的指针类型。 Because of this issue in current C++, it's necessary to help out the compiler by using. 由于当前C ++中存在此问题,因此有必要使用来帮助编译器。

get_func((const IBase*)&b);

secondly, it may be better to add virtual to 其次,最好将virtual添加到

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

,since IBase::func is defined as a virtual member function. ,因为IBase :: func被定义为虚拟成员函数。 (This isn't necessary for all compilers: C++ "virtual" keyword for functions in derived classes. Is it necessary? ). (这并不是所有编译器都必需的: 派生类中的函数的C ++“ virtual”关键字。是否有必要? )。

With these changes, code below outputs what's expected: 进行了这些更改后,以下代码将输出预期的结果:

Unknown
From MyClass

Code: 码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM