具有模板化返回类型的虚拟成员函数的实例化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有模板化返回类型的虚拟成员函数的实例化相关的知识,希望对你有一定的参考价值。

我有一个基类(我想用它来模拟接口)

template<typename TType>
class Base
{
public:
    virtual SomeTemplatedClass<TType> GetTheObject() = 0;
}

显然是派生类

template<typename TType>
class Derived : public Base<TType>
{
public:
    virtual SomeTemplatedClass<TType> GetTheObject() = 0;
}

但对于某些特定的类型,我有意专门化'GetTheObject'

template<> 
SomeTemplatedClass<int> Derived<int>::GetTheObject()
{
    return 5;
}

当我尝试使用时,Visual Studio 2015抱怨它无法实例化抽象类

Derived<int>

甚至为模板版本提供抛出行为

class Derived : public Base<TType>
{
public:
    virtual SomeTemplatedClass<TType> GetTheObject() override
    {
        throw <something>;
    }
}

让一切都编译好。所以我的问题是:为什么我需要提供一般的行为,当我有一个特定的行为,而唯一需要的行为?

答案

您不需要实现泛型GetTheObject,但您需要将其声明为非纯。否则你的课是抽象的。

template<typename TType>
class Derived : public Base<TType>
{
public:
     virtual SomeTemplatedClass<TType> GetTheObject();
}

您现在可以专门使用该功能。

您将无法实例化任何非专业派生对象(您将收到链接器错误)。

您不能通过简单地在类之外提供其纯虚拟成员的实现来使抽象类具体化。

class A { virtual void f() = 0; }; // A is abstract
void A::f() {} // A is still abstract

模板也不例外。

template <int> class A { virtual void f() = 0; }; // A is abstract
template <int k> void A<k>::f() {} // A is still abstract

函数专业化没有任何改变。

template <int> class A { virtual void f() = 0; }; // A is abstract
template <int k> void A<k>::f() {} // A is still abstract
template <> void A<42>::f() {} // srsly are you kidding?

如果您希望通用案例是抽象的并且具体的案例具体化,则需要专门化整个类,而不仅仅是纯函数实现。

以上是关于具有模板化返回类型的虚拟成员函数的实例化的主要内容,如果未能解决你的问题,请参考以下文章

2022暑期复习-Day6

即使我在 .cpp 文件中实例化一个虚拟对象,在 .cpp 文件中定义模板函数也不起作用

C++模板详解

类型存储和变量

为啥未使用的成员模板函数的类模板实例化失败

C++ 模板详解(转)