-
Notifications
You must be signed in to change notification settings - Fork 0
Reader с зафиксированными аргументами
Предположим, что мы столкнулись с задачей считать vector<int>
из n
int-ов
, каждый из которых от l
до r
. Заметим, что [DefaultReader<vector<int>>
](Default Readers Documentation#wiki-vector) принимает экземпляр класса Reader<int>
. А у [DefaultReader<int>
](Default Readers Documentation#wiki-int) есть нужный нам метод чтения чисел из отрезка. Но мы не можем "сказать", чтобы DefaultReader<int>
при передаче в DefaultReader<vector<int>>
вызывал у себя метод read(l, r)
, а не метод read()
, который по умолчанию вызывается в DefaultReader<vector<int>>
.
Для этого есть функция, которая будет, во-первых, принимать reader (типа T
) и аргументы, которые мы хотим передавать при каждом вызове метода read()
(в рассматриваемом примере это l
и r
), и, во-вторых, выдавать нужный нам superReader
(также типа T
), так что reader.read(Args) == superReader.read()
.
Таких функций даже две:
-
make_reader (T reader, Args... args)
- возвращает Reader, который при вызове методаread
будет вызыватьreader.read(args...)
.
Использование (реализация чтения в ситуации, описанной в начале):auto reader = make_reader(DefaultReader<int>(), l, r);
- считает число (если оно не принадлежит отрезку[l; r]
, то выдает WA). -
make_default_reader (Args args)
- возвращаетDefaultReader<T>
, который при вызове методаread
будет вызыватьDefaultReader().read(args...)
.
Реализованы данные обертки в данный момент в виде класса ReaderWrapper
, но не стоит считать, что так будет всегда.
Использование:
auto reader = make_default_reader<int>(l, r)
- считает число от l
до r
.
Внимание! Пример неправильного использования: (TODO: добиться, чтобы такое не компилировалось)
Reader<int> reader = make_default_reader<int>(l, r)
- неверно, так как make_default_reader<int>(l, r)
создаст наследника класса Reader<int>
и наше присваивание "уничтожит его индивидуальность", то есть оставит пустую внутренность, соответствующую классу Reader. Поэтому вы можете добиться того, что вам нужно, либо используя auto
, либо указав полное имя класса, что делать не рекомендуется, ибо инвариантность возвращаемого типа не гарантируется в последующих версиях библиотеки.