Const правильность с 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>с обоими process_1 а также process_2, Решения, которые я рассмотрел до сих пор, включают:

  • Используя бросок в стиле C или reinterpret_cast на ссылку на vec
  • Написание моей собственной справочной оболочки, которая имеет T& get() а также T const & get() const вместо T& get() const
  • Рефакторинг, например, с помощью методы, которые принимают обертку вместо вектора
  • Наличие копий вектора с и без const
  • Не используется const в reference_wrapperаргумент

Ничто из этого не кажется очень элегантным. Есть ли что-то еще, что я мог сделать?

1

Решение

Адаптеры дальности.

Адаптер диапазона принимает диапазон в качестве входных данных (контейнер является диапазоном, так как он имеет begin а также end возвращает итераторы) и возвращает диапазон с различными свойствами.

Вы бросили свои справочные обертки на const Вариант, когда вы разыменовываете итератор.

boost есть итераторы, которые сделают это за вас (преобразователи итераторов), и инструменты, помогающие писать соответствующие итераторы, но это можно сделать с нуля с некоторой работой.

Небольшая дополнительная работа могла бы даже сохранить разумные имена.

2

Другие решения

Даже не имея элегантности, я сделал бы справочную обертку:

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

Это крошечный класс, моделирующий исходные требования.

1

По вопросам рекламы [email protected]