使用reference_wrapper构造const正确性

时间:2014-06-22 14:44:58

标签: c++ c++11 reference-wrapper

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

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。到目前为止我考虑过的解决方案包括:

  • 在对reinterpret_cast
  • 的引用中使用C风格的演员或vec
  • 编写自己的参考包装,其中包含T& get()T const & get() const而不是T& get() const
  • 用例如重构采用包装器而不是向量的方法
  • 拥有和不包含const
  • 的矢量副本
  • const的参数
  • 中未使用reference_wrapper

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

2 个答案:

答案 0 :(得分:2)

范围适配器。

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

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

boost有迭代器可以为你做这个(转换迭代器),以及帮助编写符合迭代器的工具,但是可以通过一些工作从头开始。

一些额外的工作甚至可以使类型名称保持清醒。

答案 1 :(得分: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;
};

这是一个模仿原始要求的小班。