c – 模板类虚函数=必须实现吗?

这段代码:

template <typename T>
struct A
{
     T t;

     void DoSomething()
     {
          t.SomeFunction();
     }
};

struct B
{
};

A<B> a;

很容易编译,没有任何投诉,只要我从来没有打电话给.DoSomething().

但是,如果我将DoSomething定义为虚函数,我将收到一个编译错误,指出B没有声明SomeFunction.我可以在某种程度上看到它为什么会发生(DoSomething现在应该在vtable中有一个条目),但我不禁觉得它并没有真正的义务.再加上很糟糕.

有没有办法克服这个问题?

编辑2:好的.我希望这次它能够做到:
假设我正在进行侵入式引用计数,因此所有实体都必须从基类Object继承.我怎样才能成为原始类型?我可以定义:

template <typename T>
class Primitive : public Object
{
    T value;
public:
    Primitive(const T &value=T());

    operator T() const;

    Primitive<T> &operator =(const T &value);
    Primitive<T> &operator +=(const T &value);
    Primitive<T> &operator %=(const T &value);

    // And so on...
};

所以我可以使用Primitive< int>,Primitive< char> …
但是Primitive< float&gt ;?怎么样?这似乎是一个问题,因为浮点数没有%=运算符.但实际上,它不是,因为我永远不会在Primitive< float>上调用operator%=.
这是模板的深思熟虑的功能之一.

如果出于某种原因,我将operator%=定义为virtual.或者,如果我要预先导出Primitive< float>从一个DLL来避免链接错误,即使我从未在Primitive< float>上调用operator%=,编译器也会抱怨.如果它只是为Primitive< float>的vtable(引发异常?)中的运算符%=填充虚拟值,那么一切都会好的.

最佳答案 将虚拟内容放入可选择的基类中……

struct Jumper
{
    virtual void Jump =0;
};

struct Crawler
{
    virtual void Crawl() =0;
};

struct JumperCrawler:
    public Jumper,
    public Crawler
{
};

template<typename T, typename Methods>
class ICanBoostJumpingAndCrawling :
    public Methods
{
    T t;
};

现在,您可以将ICanBoostJumpingAndCrawling与Jumper,Crawler或JumperCrawler一起用作Methods模板参数;意识到你需要从它派生,以便你可以在子类中实现跳跃和/或爬行.

仅供参考,这使得“ICanBoostJumpingAndCrawling”这个名称完全具有误导性,因为它可能会也可能不会这样做;这意味着它应该被重命名为“Booster”之类的东西.

点赞