Opened 3 years ago

Closed 3 years ago

#746 closed ожидается проверка (задача сдана)

WW_linq Garaev Timur lab_14

Reported by: Garaev Timur Owned by: Антон Филатов
Component: WW_linq Version: 3.0
Keywords: Cc:

Description

Сделано многое, но страшное еще впереди.

Сейчас:

1) Почти сапускается minimal_smoke_test. Ругается, если массив будет константным, как в примере. Если убрать это, останется только проблемя из 2)

2) После пары часов войны с языком и собой идей, как все-таки реализовать select (да еще и лениво!) не прибавилось.
Я там в целом немного пооставлял комментариев в непонятных моментах. Если на некоторые из них вы поможете мне ответить, буду безмерно благодарен.

3) За стиль хочется отрвать мне руки, но тогда лабу я не допишу. Давайте повременим с этим.

Ну и в целом как можно больше замечаний приветсвуется, чтобы было над чем поработать ко второму дедлайну.

Change History (5)

comment:1 Changed 3 years ago by Антон Филатов

Type: ожидается проверкаожидаются исправления

Давайте сначала по вашим комментариям в коде пройдёмся:
конструктор where:

    where_enumerator(enumerator<T> &parent, F func) : parent_(parent), func_(func) {

        // Is it OK to drop elements in constructor? 
        // Is there any ideas to do it in ++ saving a 'lazy'? 
        while (bool(parent_) && !func_(*parent_)) {
            ++parent_;
        }
    }

не просто ок - а прям как надо. Вы не дропаете, вы своему энумератору показываете, где первый элемент, который ему подходит. В ++ тоже надо делать так, как делаете вы. Можно смотреть на это под таким углом - цель оператора* - вернуть то, на что энумератор сейчас показывает. Ключевое слово сейчас. Оператору* не нужно передвигаться по контейнеру. За него это должны делать конструктор и ++. Единственное, до чего могу докопаться - копипаста в кнструкторе и в ++

По селекту такая петрушка:
вы правильно поняли, что наследуемся от энумератора с одним шаблоном, а в конструктор суём другой шаблон. Волшебство каста от U к T мы возлагаем на predicate. Но при этом хранить T value в классе вам не только можно, но и крайне полезно. Тогда в операторе* вы сможете напрямую вернуть это value, а в конструкторе и операторе ++ можно делать что-то вроде этого

    if (parent_) {
      value_ = predicate_(*parent_);
    }

return predicate(*parent) doesn't works. Why?! - кажется в хорошем случае он должен работать. Не будет работать, если parent == false. Да и ещё раз, задача оператора* - вернуть то, что уже посчитали, а не считать что-то по вызову

В until_enumerator::operator bool забываете (bool)parent
Я бы порекомендовал завести в этом энумераторе отдельную булеву переменную, которая будет хранить результат func_(parent) - и назвать её как-нибудь говоряще, чтобы !func_(*parent_); не смущало

В остальном выглядит вполне достойно, но ставить баллы пока рано

comment:2 Changed 3 years ago by Garaev Timur

Type: ожидаются исправленияожидается проверка
Version: 1.02.0

Сейчас оба теста из репозитория компилируются и даже проходят все ассерты!
Расставил констант, вроде проблема с ними решилась. Наверное за эту посылку даже получится поставить не 0.

В целом рубрика комментарии с вопросами еще актуальна, так что если когда будете глядеть код заметите и прокомментируете их как в прошлый раз -- будет очень круто!

comment:3 Changed 3 years ago by Антон Филатов

Type: ожидается проверкаожидаются исправления

Падают следующие тесты:

  • на drop. Зачем вы в ++ снова обращаетесь к count? вы констркторе сдвинули - и нормально. кажется, что в вашем if count-- рано или поздно станет отриуательным
  • на until вот такой тест падает:
    auto xs = std::vector<int>{10, 20, 30};
    auto res = from(xs.begin(), xs.end()).until([](int x) {
      assert(x == 10 || x == 20 || x == 30);
      return false;
    }).to_vector();
    assert((std::vector<int>{10, 20, 30}) == res);

причём падает именно assert внутри лямбды

А также в until, where и select возникают копии функции, которая им передаётся. Это можно проверить, сделав класс-обёртку над функцией, определить для него оператор() и сделать говорящий контруктор копирования

Стиль:

  • в where и select хочется избежать копипасты

По вашему вопросу перед *_eq

    // Is it true that such a solution was expected to be correct for these two functions?
    // Is it possible to come up with a way to pass element by reference, not by value?
    // (cuz they can be large and these are unnecessary copies)

сделайте const T& в этих лямбдах - и проблема решена

Сейчас ваша программа выглядит очень близко к правде

6/10

comment:4 Changed 3 years ago by Garaev Timur

Type: ожидаются исправленияожидается проверка
Version: 2.03.0

Как же хочется десяточку.

comment:5 Changed 3 years ago by Антон Филатов

Resolution: задача сдана
Status: assignedclosed

10/10

Note: See TracTickets for help on using tickets.