1. C++ / Говнокод #20503

    +8

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    #include <vector>
    #include <iostream>
    
    template<class T>
    struct reverse_view_impl {
    	const T& cont;
    	reverse_view_impl(const T& cont): cont(cont) {}
    	using iterator = typename T::const_reverse_iterator;
    };
    template<class T>
    reverse_view_impl<T> reverse_view(const T& cont) {
    	return reverse_view_impl<T>(cont);
    }
    
    template<class T>
    typename reverse_view_impl<T>::iterator begin(const reverse_view_impl<T>& view) {
    	return view.cont.crbegin();
    }
    template<class T>
    typename reverse_view_impl<T>::iterator end(const reverse_view_impl<T>& view) {
    	return view.cont.crend();
    }
    
    std::vector<int> one_two_three() { return { 1, 2, 3 }; }
    
    int main() {
    	for (auto i : reverse_view(one_two_three())) {
    		std::cout << i << std::endl;
    	}
    }

    // Surprise, motherfucker

    Запостил: Bobik, 10 Августа 2016

    Комментарии (22) RSS

    • ибо нехер брать сылку на rvalue

      п.с. чет прям угнетает количество бойлерплейт кода, необходимого для реализации четырех версий итераторов (const/mutable forward/reverse)
      Ответить
      • > бойлерплейт
        Boost.Iterator
        Ответить
        • не получалось еще ни разу этим пользоваться, к сожалению.

          на самом деле, если херней не страдать, и без фанатизма к проблеме подходить, то простенькие и достаточные итераторы делаются достаточно просто и быстро. 90% приложений покрываются begin()/end() и operator++. я, к слову, делал преимущественно для того что бы не трахатся с объяснениями как пользоваться самопальными контейнерами.
          Ответить
          • дык никакого фанатизма и не надо
            header-only библиотека, который весь этот бойлерплейт возьмет на себя
            всё что надо, это объявить чуток приватных методов определенной сигнатуры, например, объясняющих как двигаться итератору и как извлекать значение
            лучше один раз сделать, чем сто раз услышать
            Ответить
            • Экий багор )))
              Ответить
            • "если херней не страдать, и без фанатизма" - это я ссылался не на Boost.Iterator, а на доморощеные попытки писать STL-like итераторы.

              потому что я в паре либ такое дело видел, и это был не детский кошмар. после этого я как раз и начал сырцы STL читать... мозги заворачивает, но после доморощеного попимаешь на кой хер они там в STL тыщи строк пишут. (что за либа уже не помню, а кошмары были с const/non-const версиями где иногда компилятор подбирал неправильную версию итератора/begin()/end() и компиляция вылетала со стандартными 10ти этажными сообщениями об ошибках. когда увидел cbegin()/cend() в C++11, невольно прослезился.)
              Ответить
        • знал бы прикуп, жил бы в сочи. Просто совсем недавно пришлось писать итератор (для многомерного массива), где-то на середине const-версии понял что хрен с ним, обойдемся.
          Ответить
    • Какой багор )))
      Ответить
    • Пространство имен внутри шаблона? Да когда же я выучу С++?
      Ответить
      • Каждая пара фигурных скобок создаёт такое "пространство имён" :)
        Ответить
        • Хмм, ну не знаю - к примеру к static переменной внутри функции так не достучишься и IDE молчит.
          Ответить
      • ты еще
        class MyClass1::MyClass2 : public SomeBase { ...
        не видел
        Ответить
        • Нее, тут моих знаний хватает, даже такое писал
          class PauseState:StateMachine::BaseState
          {
          //...
          };
          Ответить
        • Классный трюк, кстати, чтобы выставить публике только фабрику шаред_поинтеров на объект.
          Ответить
      • лет 15-20 активного использ0вания С++ и ты будешь профи!
        Ответить
      • Такими темпами не скоро.
        Ответить
    • Я, когда игрался с подобными вещами, делал две перегрузки шаблона функции, которая создаёт view. Обе принимали T&& ("универсальную" a.k.a. forwarding ссылку, которая привязывается к чему угодно).
      И у каждой было своё условие внутри enable_if (проверка типа T на is_lvalue_reference), чтобы безошибочно отделять lvalue от rvalue аргументов.
      Перегрузка, работающая с lvalue, просто захватывала ссылку на оригинальный контейнер.
      Перегрузка для rvalue создавала новый объект и мувала в него "умирающий" аргумент-контейнер.
      Да, типы возвращаемых значений были разные, но это не было проблемой в моём случае.
      Ответить

    Добавить комментарий