простой просмотр с использованием STL - PullRequest
1 голос
/ 07 апреля 2020

Я хочу создать базовый c класс 'view', который будет просто контейнером константных ссылок на существующие объекты, только со стандартом C ++ и STL. Я могу сделать это с

template<typename T>
using view = vector<reference_wrapper<const T>>

, который прекрасно работает с остальной частью STL, как библиотека алгоритмов. Проблема в том, что пользователь должен вызвать .get () для объектов в этом представлении, чтобы сделать что-нибудь полезное (что раздражает в плане удобства использования). Я ищу простой способ расширить это так, чтобы методы доступа автоматически возвращали const T&, а не std::reference_wrapper<const T>

. Это можно сделать без создания нового класса View, производного от vector и переопределяющего соответствующие методы?

1 Ответ

0 голосов
/ 07 апреля 2020

Существует несовершенное решение.

class C {
public:
    void fun() { cout << "C::fun();" << endl; }
};

template <class _Ty>
class myreference_wrapper : public _Weak_types<_Ty>::type, public _Ty { // stand-in for an assignable reference
public:
    static_assert(is_object_v<_Ty> || is_function_v<_Ty>,
        "reference_wrapper<T> requires T to be an object type or a function type.");

    using type = _Ty;

    template <class _Uty, enable_if_t<conjunction_v<negation<is_same<_Remove_cvref_t<_Uty>, myreference_wrapper>>,
        _Refwrap_has_ctor_from<_Ty, _Uty>>,
        int> = 0>
        myreference_wrapper(_Uty&& _Val) noexcept(noexcept(_Refwrap_ctor_fun<_Ty>(_STD declval<_Uty>()))) {
        _Ty& _Ref = _STD forward<_Uty>(_Val);
        _Ptr = _STD addressof(_Ref);
    }

    operator _Ty& () const noexcept {
        return *_Ptr;
    }

    _NODISCARD _Ty& get() const noexcept {
        return *_Ptr;
    }

    template <class... _Types>
    auto operator()(_Types&&... _Args) const -> decltype(_STD invoke(get(), _STD forward<_Types>(_Args)...)) {
        return _STD invoke(get(), _STD forward<_Types>(_Args)...);
    }

private:
    _Ty* _Ptr;
};

template<typename T>
using view = vector<myreference_wrapper<const T>>;
int main() {
    C c;
    view<C>v;
    v.push_back(c);
    v[0].fun();
    return 0;
}

class myreference_wrapper скопирован из заголовка std, только что изменил его наследование.

Решение не очень хорошее, он не может решить основные типы c, но я не могу дать лучший.

На самом деле, я думаю, что идеального решения может не существовать. vector<reference_wrapper<const T>>::operator[] возвращает тип reference_wrapper<const T>, как вы можете иметь дело с reference_wrapper<const T> так же, как T? Эмм ... Возможно, мои знания недостаточно богаты.

...