tsnorri
tsnorri

Reputation: 2097

Const correctness with reference_wrapper

In various situations I have a collection (e.g. vector) of objects that needs to be processed by a number of functions. Some of the functions need to modify the objects while others don't. The objects' classes may inherit from an abstract base class. Hence, I have something like this:

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);

Obviously (?) I can't pass the same vector of std::reference_wrapper<A>s to both process_1 and process_2. Solutions I've considered so far include:

None of these seems very elegant. Is there something else I could do?

Upvotes: 3

Views: 1432

Answers (2)

user2249683
user2249683

Reputation:

Even lacking elegance, I would make a reference wrapper:

#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;
};

It is a tiny class modeling the original requirements.

Upvotes: 1

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275575

Range adapters.

A range adapter takes a range as input (a container is a range, as it has begin and end returning iterators), and returns a range with different properties.

You'd cast your reference wrappers to the const variant when you dereference the iterator.

boost has iterators that will do this for you (transform iterators), and tools to help write conforming iterators, but it can be done from scratch with some work.

A bit of extra work could even keep the typenames sane.

Upvotes: 3

Related Questions