Кресты / Говнокод #25520 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
#include <iostream>
#include <functional>
#include <array>
#include <iterator>

template <class T>
class Filter : public std::iterator<
                 std::input_iterator_tag,
                 typename std::iterator_traits<T>::value_type,
                 typename std::iterator_traits<T>::difference_type,
                 typename std::iterator_traits<T>::pointer,
                 typename std::iterator_traits<T>::reference
               >
{
private:
  typedef typename std::iterator_traits<T>::value_type value_type;
  std::function<bool(value_type)> m_predicate;
  T m_begin, m_end;
  value_type m_current;

public:
  Filter(T t_begin, T t_end, std::function<bool(value_type)> t_predicate)
    : m_begin(t_begin), m_end(t_end), m_predicate(t_predicate)
  {
  }
  
  Filter<T>& begin()
  {
    return ++*this;
  }
  
  Filter<T>& end()
  {
    return *this;
  }
  
  value_type operator* ()
  {
    return m_current;
  }
  
  Filter<T>& operator++ ()
  {
    do {
      m_current = *m_begin;
      ++m_begin;
    } while (m_begin != m_end && !m_predicate(m_current));
    return *this;
  }
  
  
  bool operator!= (Filter<T>& t_right)
  {
    return m_begin != t_right.m_end;
  }
};


int main()
{
  std::array<int, 10> arr{ {4, 35, 0, 23, 0, 0, 5} };
  for (auto i : Filter<typename std::array<int,10>::iterator>(arr.begin(), arr.end(), [](int x){return x != 0;})) {
    std::cout << i << " ";
  }
}

Запостил: Lemming Lemming, (Updated )

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

  • Кстати, begin и end могут иметь разные типы, правда я такококого не встречал.
    Ответить
      • Не будет работать с разными типами у аргументов.
        В ихнем фориче, начиная с C++17, зачем-то сделали поддержку разных типов у begin и end, значит где-то они могут быть разные:
        // https://en.cppreference.com/w/cpp/language/range-for
        
        // до C++17
        {
        auto && __range = range_expression ; 
        for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) { 
        range_declaration = *__begin; 
        loop_statement 
        } 
        } 
        
        // опосля
        {
        auto && __range = range_expression ; 
        auto __begin = begin_expr ;
        auto __end = end_expr ;
        for ( ; __begin != __end; ++__begin) { 
        range_declaration = *__begin; 
        loop_statement 
        } 
        }
        Но я в крестах плохо шарю, могу ошибацца.
        Ответить
    • Ckbpbcnsq fk[bvbr d ndj`v kbwt jgznm ds[jlbn yf cdzpm&
      Ответить
  • Сп4441234а54354354433213214324ми534543324те?
    Ответить
  • std::function<bool(value_type)>

    Как такие параметры шаблона называются? Нету нигде про них на cppreference.
    Ответить
    • У них нет особого названия. Это просто тип функции
      Ответить
        • Вполне себе существует. Переменную, конечно, такого типа не обьявишь (только ссылку или указатель). Но использовать можно как тип:
          float bar(int) { return 3.14f; }
          
          int main() {
            using T = float(int);
            T &baz = bar;
            static_cast<void>(baz);
          }


          https://wandbox.org/permlink/qjEkHE9W3Uajw3Yq
          Ответить
          • тогда компилятор ругнется на то, что не успел посмотреть, к примеру, крутой конвертер частоты но сама функция принимает void myfree(void **ptr) { return 3.14f; } www не само собой.
            Ответить
            • При всей полезности, механизм подтипов несколько ограничен, т. к. разрешает указывать лишь непрерывные диапазоны значений для числовых и перечислимых типов. Это подтолкнуло разработчиков языка Ада 2012 ввести предикаты подтипов, которые можно добавлять к определениям типов и подтипов. Как показала практика, необходимо иметь два различных механизма в зависимости от того, является ли предикат статическим или динамическим. Оба используют выражения типа Boolean, но статический предикат разрешает лишь некоторые
              типы выражений, в то время как динамический применим в более общем
              случае.

              Допустим мы оперируем сезонами года и имеем следующее определение месяцев:
              type Month is (Jan, Feb, Mar, Apr, May, Jun,
              Jul, Aug, Sep, Oct, Nov, Dec);


              Мы хотим иметь отдельные подтипы для каждого сезона. Для северного
              полушария зима включает декабрь, январь и февраль. Поэтому нам нужен подтип, включающий значения Dec , Jan и Feb.
              Мы не можем воспользоваться ограничением диапазона здесь, но можем
              использовать статический предикат следующим образом:
              subtype Winter is Month
              with Static_Predicate => Winter in Dec | Jan | Feb;


              Это гарантирует, что объекты типа Winter могут содержать только Dec , Jan и Feb. Подобная синтаксическая конструкция со словом with введена в Ада 2012 и называется аспектом.

              Данный аспект проверяется при инициализации переменной по умолчанию, присваивании, преобразовании типа, передаче параметра и т. д. Если проверка не проходит, то возбуждается исключение Assertion_Error.

              Если условие проверки не является статическим, то необходимо
              использовать динамический предикат. Например:
              function Is_Good (X : T) return Boolean;
              subtype Good_T is T
              with Dynamic_Predicate => Is_Good (Good_T);
              Ответить
      • Сразу видно, что ты немец. Ты эсцет.
        Ответить
  • Filter<typename std::array<int,10>::iterator>(arr.begin(), arr.end(), [](int x){return x != 0;})


    Для такого придумали user-defined template deduction guides:
    template <typename Iterator, typename Value = typename std::iterator_traits<Iterator>::value_type>
    Filter(Iterator, Iterator, std::function<bool(Value)>) -> Filter<Iterator>;


    Тогда:
    Filter(arr.begin(), arr.end(), [](int x) { return x != 0; })


    https://wandbox.org/permlink/bgDIOrsi8TWrwSxS
    Ответить
  • Спама сегодня нет. Наверно гуестинхо починил свою ректификационную колонну.
    Ответить

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

Я, guest, находясь в здравом уме и твердой памяти, торжественно заявляю:

    А не использовать ли нам bbcode?


    8