2

在各种情况下,我有一个需要由许多函数处理的对象集合(例如向量)。有些函数需要修改对象,而有些则不需要。对象的类可以从抽象基类继承。因此,我有这样的事情:

class A
{
public:
    virtual void foo() const = 0;
    virtual void bar() = 0;

    /* ... */
};

void process_1(std::vector<std::reference_wrapper<A>> const &vec);
void process_2(std::vector<std::reference_wrapper<A const>> const &vec);

显然(?)我不能将std::reference_wrapper<A>s 的相同向量同时传递给process_1process_2。到目前为止我考虑过的解决方案包括:

  • 使用 C 风格的强制转换或reinterpret_castvec
  • 编写我自己的引用包装器,它有T& get()T const & get() const而不是T& get() const
  • 使用例如采用包装器而不是向量的方法进行重构
  • 有和没有向量的副本const
  • 不使用constinreference_wrapper的论点

这些看起来都不是很优雅。还有什么我可以做的吗?

4

2 回答 2

3

范围适配器。

范围适配器将范围作为输入(容器是范围,因为它具有beginend返回迭代器),并返回具有不同属性的范围。

const当您取消引用迭代器时,您会将引用包装器转换为变体。

boost具有可以为您执行此操作的迭代器(转换迭代器),以及帮助编写符合要求的迭代器的工具,但可以通过一些工作从头开始完成。

一些额外的工作甚至可以保持类型名称的健全。

于 2014-06-22T15:02:00.370 回答
1

即使缺乏优雅,我也会做一个参考包装:

#include <functional>

template <typename T>
class ReferenceWrapper
{
    public:
    ReferenceWrapper(T& ref)
    :   m_ref(ref)
    {}

    ReferenceWrapper(const std::reference_wrapper<T>& ref)
    :   m_ref(ref)
    {}

    const T& get() const noexcept { return m_ref.get(); }
    T& get()  noexcept { return m_ref.get(); }

    operator const T& () const  noexcept { return m_ref.get(); }
    operator T& ()  noexcept { return m_ref.get(); }

    private:
    std::reference_wrapper<T> m_ref;
};

这是一个模拟原始需求的小类。

于 2014-06-22T18:39:38.390 回答