摘要中的 C++ 迭代器参数 class

C++ iterator argument in abstract class

我想要一个抽象的 class,其读写方法如下:

template<typename Iterator>
virtual void read(uint64_t adr, Iterator begin, Iterator end) const = 0;    

template<typename Iterator>
virtual void write(uint64_t adr, Iterator begin, Iterator end) const = 0;

有没有办法实现这样的目标?

既然不能有虚模板方法,就想

  1. 摆脱抽象 class 并改用模板。 在模板中,我假设有一个采用迭代器的 read/write 方法。
  2. 也将抽象 class 设为模板并传递迭代器类型。

这些方法中的一种是干净的吗? 我在 C++11 顺便说一句

Is one of these ways a clean one?

是:使用静态多态性而不是 virtual 函数。当通过模板传递类型时,它不会被擦除,因此不需要预先生成的虚拟表,因此您可以进行进一步的模板实例化——这就是您的用例所要求的。

方案一(推荐)

因此,如果您的摘要 class 仅用作“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 */ }
};

并通过该摘要 class 将您的实现的用法 class 替换为

template<typename Impl> void use_any_impl(Impl&&) { /* work */ }

但是,如果您的摘要 class 包含一些要被继承的 logic/data,您可以保留 class 但去掉任何 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 提供的),这对于原始数组来说似乎是合理的read/write 操作,你可以只使用原始指针:

virtual void  read(uint64_t, unsigned char*, unsigned char*) const = 0;
virtual void write(uint64_t, unsigned char*, unsigned char*) const = 0;