摘要中的 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;
有没有办法实现这样的目标?
既然不能有虚模板方法,就想
- 摆脱抽象 class 并改用模板。
在模板中,我假设有一个采用迭代器的 read/write 方法。
- 也将抽象 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
如果你的 template
d Iterator
s 总是(或可以减少到)导致原始数组存储(例如 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;
我想要一个抽象的 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;
有没有办法实现这样的目标?
既然不能有虚模板方法,就想
- 摆脱抽象 class 并改用模板。 在模板中,我假设有一个采用迭代器的 read/write 方法。
- 也将抽象 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
如果你的 template
d Iterator
s 总是(或可以减少到)导致原始数组存储(例如 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;