这些方法之一是干净的吗?
是的:使用静态多态性而不是 virtual 函数。当一个类型通过模板传递时,它不会被删除,因此不需要预先生成的虚拟表,因此您可以引发进一步的模板实例化——这就是您的用例所要求的。
解决方案 1(推荐)
因此,如果您的抽象类仅用作“interface”,请将其删除并直接在“实现”中写入read/write:
struct Impl {
template<typename Iterator> void read(uint64_t, Iterator, Iterator) const { /* work */ }
template<typename Iterator> void write(uint64_t, Iterator, Iterator) const { /* work */ }
};
并通过该抽象类替换实现类的用法
template<typename Impl> void use_any_impl(Impl&&) { /* work */ }
但是,如果您的抽象类包含一些要继承的逻辑/数据,您可以保留该类但删除任何内容virtual:
class Abstract {
protected: ~Abstract() = default;
public: constexpr int inherit_me() const { return 42; }
};
class Impl: public Abstract { /* read() and write() same as above */ };
/* use_any_impl() same as above */
解决方案 2
如果您的templated Iterators 总是(或可以减少为)导致原始数组存储(例如,std::vector<unsigned char>::data 提供的一个),这对于原始读/写操作似乎是合理的,您可以只使用原始指针:
virtual void read(uint64_t, unsigned char*, unsigned char*) const = 0;
virtual void write(uint64_t, unsigned char*, unsigned char*) const = 0;