【问题标题】:C++ iterator argument in abstract class抽象类中的 C++ 迭代器参数
【发布时间】:2021-12-17 05:26:31
【问题描述】:

我想要一个具有读写方法的抽象类,例如:

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. 摆脱抽象类并改用模板。 在模板中,我假设有一个采用迭代器的读/写方法。
  2. 将抽象类也设为模板并传递迭代器类型。

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

【问题讨论】:

    标签: c++ templates inheritance


    【解决方案1】:

    这些方法之一是干净的吗?

    是的:使用静态多态性而不是 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&lt;unsigned char&gt;::data 提供的一个),这对于原始读/写操作似乎是合理的,您可以只使用原始指针:

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

    【讨论】:

    • 我可以用template&lt;typename Impl&gt; void use_any_impl(std::unique_ptr&lt;Impl&gt;&amp;&amp;) { /* work */ }代替template&lt;typename Impl&gt; void use_any_impl(Impl&amp;&amp;) { /* work */ }
    • @yannick818 如果您打算将Impl(由unique_ptr 持有)的所有权传递给use_any_impl,则接受std::unique_ptr&lt;Impl&gt;(不需要&amp;&amp;)是您的解决方案。如果只是在函数调用期间借用它,请留在Impl&amp;&amp; 并像use_any_impl(*unique) 一样调用函数。
    • @yannick818 请注意,如果您的unique_ptr 出现在抽象类解决方案中以允许类似auto unique_impl = std::make_unique&lt;Impl&gt;(); Abstract* p = unique_impl.get() 的内容,则解决方案1 ​​不再需要它。简单的Impl impl 可以完成这项工作。编辑上一条评论:有关&amp;&amp;(右值参考与转发参考)的说明,请参阅stackoverflow.com/questions/40819058/…
    猜你喜欢
    • 2011-04-27
    • 2013-04-07
    • 2018-02-06
    • 2014-02-02
    • 2023-03-29
    • 2012-11-20
    • 1970-01-01
    • 2015-09-23
    • 2014-10-27
    相关资源
    最近更新 更多