Opened 6 years ago
Closed 6 years ago
#278 closed ожидается проверка (задача сдана)
HA4: function
Reported by: | goncharov.artem | Owned by: | rutsky,grabovoy.philipp |
---|---|---|---|
Priority: | проверка | Milestone: | ha4-deadline |
Component: | HA#4 function | Version: | 1.0 |
Keywords: | Cc: |
Description
Посмотрите, пожалуйста.
Change History (13)
comment:1 Changed 6 years ago by
Type: | ожидается проверка → ожидаются исправления |
---|
comment:2 Changed 6 years ago by
Tested revision 689 by goncharov.artem.
Smoke tests
test | stage | result | info | log |
---|---|---|---|---|
SUCCESS | ||||
FAILURE | exit code 139 | |||
Common header used in some tests: common.h
comment:3 Changed 6 years ago by
Tested revision 689 by goncharov.artem.
Main tests
test | stage | result | info | log |
---|---|---|---|---|
SUCCESS | ||||
FAILURE | exit code 139 | |||
Common header used in some tests: common.h
comment:4 Changed 6 years ago by
Tested revision 689 by goncharov.artem.
Main tests
test | stage | result | info | log |
---|---|---|---|---|
SUCCESS | ||||
FAILURE | exit code 139 | |||
SUCCESS | ||||
FAILURE | exit code 139 | |||
Common header used in some tests: common.h
comment:5 Changed 6 years ago by
Tested revision 689 by goncharov.artem.
Main tests
test | stage | result | info | log |
---|---|---|---|---|
SUCCESS | ||||
FAILURE | exit code 139 | |||
SUCCESS | ||||
FAILURE | exit code 139 | |||
Common header used in some tests: common.h
comment:6 Changed 6 years ago by
Tested revision 689 by goncharov.artem.
Main tests
test | stage | result | info | log |
---|---|---|---|---|
SUCCESS | ||||
FAILURE | exit code 139 | |||
Common header used in some tests: common.h
comment:7 Changed 6 years ago by
Tested revision 714 by goncharov.artem.
All tests passed. Good job!
comment:8 Changed 6 years ago by
Type: | ожидаются исправления → ожидается проверка |
---|
comment:9 Changed 6 years ago by
Milestone: | ha4-milestone2 → ha4-deadline |
---|---|
Type: | ожидается проверка → ожидаются исправления |
Привет!
- В
function_pointer_cast
достаточноreinterpret_cast
- Почему в этом методе вызывается так параметризованный
create
? Я сходу не составил хороший пример (компилятор все соптимизировал), это же может вести к вложенностиfunction
друг в друга.function(function<ResT2(ArgsT2...)> const &other) { details::DataManager<function<ResT2(ArgsT2...)>>::create(container, other); ....
- (Чисто стилистическое) странная получается роль у
DataManager
, не совсем соответствует неймингу: он скорее походит на какой-тоMethodsPreparator
:)
comment:10 Changed 6 years ago by
Tested revision 820 by goncharov.artem.
All tests passed. Good job!
comment:11 Changed 6 years ago by
Здравствуйте!
Первое и третье поправил. На счет второго: не знаю, как от этого избавиться, ведь если в конструктор передан function с другой сигнатурой, то никак нельзя получить информацию о типе объекта-функтора, который лежит внутри. А без этого не получится создать требуемые методы (invoker, deleter, copier). Поэтому для такого случая вызывается обычный конструктор для объекта-функтора и в результате получается вложенность. На сколько я понял, в стандартной библиотеке используется такой же подход, и тоже присутствует вложенность. От этого возможно избавиться?
comment:12 Changed 6 years ago by
Type: | ожидаются исправления → ожидается проверка |
---|
comment:13 Changed 6 years ago by
Resolution: | → задача сдана |
---|---|
Status: | new → closed |
Да, сорри, я при первичном просмотре проигнорил другие типы аргументов. С ними сохранения всего функтора не избежать.
Замечание в общем по решению:
Работу с copier
, invoker
, deleter
хорошо было бы инкапсулировать в "интерфейс" — класс с чисто виртуальными методами (copy
и invoke
было бы достаточно):
class invoker { public: invoker() = default; virtual ~invoker() = default; virtual ReturnType invoke(Args ... args) = 0; virtual std::unique_ptr<invoker> clone() = 0; };
Тогда можно хранить в union Any
указатель на функцию с нужной сигнатурой, и указатель на такой класс. При создании fn::function
от функтора (и прочих комбинациях) в union по указателю на класс давайте сторить то, что реализует этот интерфейс + сохранит знание о произвольном функторе — экземпляр такого класса:
template<class Func> class func_invoker : public invoker { public: explicit func_invoker(Func & func) : func(func) {} ReturnType invoke(Args ... args) override { return func(std::forward<Args>(args)...); } std::unique_ptr<invoker> clone() override { return std::make_unique<func_invoker<Func>>(func); }; ~func_invoker() override = default; private: Func func; };
В чем преимущества использования такой штуки (по сравнению с текущим решением)?
- Безопаснее и оптимальнее за счет использования VDT: нет возможности "забыть сохранить" указатель на нужный метод в коде (хотя можно забыть, например, объявить деструктор виртуальным), вызов по нужному адресу обеспечивает компилятор, пользуется своим хранилищем.
- Безопаснее из-за отсутствия
reinterpret_cast
-ов: компилятор в compile-time выберет правильные приведения типов для аргументов.
Tested revision 599 by goncharov.artem.
Smoke tests
test
stage
result
info
log
run_function_smoke_test.cpp
run_function_smoke_test-gcc62.log
Common header used in some tests: common.h