我有一个基类(我想用它来模拟接口)
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>;
}
}
让一切都编译好。 所以我的问题是:为什么我需要提供一般的行为,当我有一个特定的行为时,是唯一需要的行为?
答案 0 :(得分:3)
您不需要实现通用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?
如果您希望通用案例是抽象的并且具体的案例具体化,则需要专门化整个类,而不仅仅是纯函数实现。