【问题标题】:Instantiation of virtual member function with templated return type具有模板化返回类型的虚拟成员函数的实例化
【发布时间】:2018-06-02 19:27:12
【问题描述】:

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

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

让一切编译。 所以我的问题是:为什么我需要提供一个通用的行为,当我有一个特定的并且唯一需要的时候?

【问题讨论】:

  • DerivedGetTheObject() 的声明中删除=0 说明符。这迫使该功能是纯虚拟的。定义函数不会改变这一点。

标签: c++11 templates visual-c++


【解决方案1】:

您不需要实现通用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?

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

【讨论】:

  • 但如果这是唯一的功能,它不应该工作吗?或者你的意思是我需要专攻整个班级,而不仅仅是这个成员?
  • 是的,全班同学,我想我写的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-10
  • 1970-01-01
  • 2018-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多