C++模板化虚函数

exc*_*bur 5 c++

C++不支持模板化的虚拟成员函数,但我有一个理想的场景.我想知道是否有人有想法如何实现这一目标.

#include <iostream>


class Foo {
public:
    virtual void bar(int ){}
    // make a clone of my existing data, but with a different policy
    virtual Foo* cloneforDB() = 0;
};


struct DiskStorage {
    static void store(int x) { std::cout << "DiskStorage:" << x << "\n"; }
};

struct DBStorage {
    static void store(int x) { std::cout << "DBStorage:" << x << "\n"; }
};

template<typename Storage>
class FooImpl : public Foo {
public:
    FooImpl():m_value(0) {}
    template<typename DiffStorage>
    FooImpl(const FooImpl<DiffStorage>& copyfrom) {
        m_value = copyfrom.m_value;
    }
    virtual void bar(int x) {
        Storage::store(m_value);
        std::cout << "FooImpl::bar new value:" << x << "\n";
        m_value = x;
    }
    virtual Foo* cloneforDB() {
        FooImpl<DBStorage> * newfoo = new FooImpl<DBStorage>(*this);
        return newfoo;
    }
    int m_value;
};

int main()
{
    Foo* foo1 = new FooImpl<DiskStorage>();
    foo1->bar(5);
    Foo* foo2 = foo1->cloneforDB();
    foo2->bar(21);
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我想克隆Foo implmemetation,但使用不同的Storagepolicy,我必须明确说明每个这样的实现:

cloneforDB()
cloneforDisk()
Run Code Online (Sandbox Code Playgroud)

模板参数会简化它.谁能想到更清洁的方法呢?请关注这个想法而不是示例,因为它显然是一个人为的例子.

Mic*_*Mic 8

通常,如果要使用虚拟模板方法,则意味着类层次结构的设计出现问题.其高级原因如下.

模板参数必须在编译时知道,这就是它们的语义.它们用于保证代码的健全性.

虚函数用于多态,即.在运行时动态调度.

因此,您不能将静态属性与运行时调度混合使用,如果您查看大图,则没有意义.

在这里,您在某处存储某些内容的事实不应该是您的方法类型的一部分,因为它只是一个行为特征,它可能在运行时更改.所以这是错误的,包括在方法的类型信息.

这就是为什么C++不允许这样做:你必须依靠多态来实现这样的行为.

一个简单的方法是将指针Storage作为参数传递给对象(如果你只想为每个类提供一个对象,则为单例),并在虚函数中使用该指针.

这样,您的类型签名不依赖于您的方法的特定行为.并且您可以在运行时更改存储(在此示例中)策略,这实际上是您应该要求的良好实践.

有时,行为可以由模板参数(例如Alexandrescu的策略模板参数)决定,但它是在类型级别而不是方法级别.