Здравствуйте, jazzer, Вы писали:
_>>Подскажите, по каким правилам это валидный код? J>
J>[func.require]
J>Define INVOKE (f, t1, t2, ..., tN, R) as INVOKE (f, t1, t2, ..., tN) implicitly converted to R.
Implicit вроде не подходит.
Думаю что по другой причине:
R operator()(ArgTypes... args) const
1 Effects: INVOKE (f, std::forward<ArgTypes>(args)..., R) (20.9.2), where f is the target object
(20.9.1) of *this.
2 Returns: Nothing if R is void, otherwise the return value of INVOKE (f, std::forward<ArgTypes>(
args)..., R).
Any expression can be explicitly converted to type cv void
А то, о чем ты говоришь — это относится лишь к поведению operator(), а не к самой возможности инстанцирования std::function с другим типом возврата (а вопрос был, как я понимаю, именно в этом).
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, jazzer, Вы писали:
_>>>>>Подскажите, по каким правилам это валидный код? J>>>>
J>>>>[func.require]
J>>>>Define INVOKE (f, t1, t2, ..., tN, R) as INVOKE (f, t1, t2, ..., tN) implicitly converted to R.
EP>>>Implicit вроде не подходит. J>>Должен подходить [basic.fundamental]: J>>
J>>Any expression can be explicitly converted to type cv void
EP>Тут же explicit, а не implicit.
Да, действительно, твоя правда. Тогда это дефект стандарта, имхо.
Потому что в вопросе речь идет о конструкторе
template<class F> function(F f);
7 Requires: F shall be CopyConstructible. f shall be Callable (20.9.11.2) for argument types ArgTypes
and return type R. The copy constructor and destructor of A shall not throw exceptions.
В данном случае R — это void (берется из типа, которым инстанцирован std::function).
Выделенное привозит нас к
A callable object f of type F is Callable for argument types ArgTypes and return type R if the expression INVOKE(f, declval<ArgTypes>()..., R), considered as an unevaluated operand (Clause 5), is well
formed (20.9.2).
Что, в свою очередь, приводит нас к тому, что я процитировал вначале:
Define INVOKE (f, t1, t2, ..., tN, R) as INVOKE (f, t1, t2, ..., tN) implicitly converted to R.
т.е. требуется наличие неявного приведения к void.
Здравствуйте, jazzer, Вы писали:
J>Да, действительно, твоя правда. Тогда это дефект стандарта, имхо.
Да, похоже на дефект. Точнее зависит от того, "что же хотел сказать автор".
Может они и имели ввиду, что код ТС неверен (просто без диагностики), а оговорка в operator() избыточна.
J>Потому что в вопросе речь идет о конструкторе
Дело в том что при instantiation конструктора, происходит instantiation вызова данного пользователем function object — так как здесь type erasure.
Поэтому я и смотрел в std::function::operator() — так как он диктует требования к тому как будет instantiate вызов function object (эта instantiation происходит во вспомогательном объекте).
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, jazzer, Вы писали:
J>>Да, действительно, твоя правда. Тогда это дефект стандарта, имхо.
EP>Да, похоже на дефект. Точнее зависит от того, "что же хотел сказать автор". EP>Может они и имели ввиду, что код ТС неверен (просто без диагностики), а оговорка в operator() избыточна.
Ну, имхо, такой код должен работать без проблем, так что, скорее всего, все-таки дефект.
Надо будет закинуть им вопрос.
J>>Потому что в вопросе речь идет о конструкторе
EP>Дело в том что при instantiation конструктора, происходит instantiation вызова данного пользователем function object — так как здесь type erasure. EP>Поэтому я и смотрел в std::function::operator() — так как он диктует требования к тому как будет instantiate вызов function object (эта instantiation происходит во вспомогательном объекте).
Да я так и понял. Просто по стандарту (N3797) получается, что этот код вообще неверен уже на этапе требований к аргументу конструктора, независимо от того, что там дальше происходит.
Здравствуйте, jazzer, Вы писали:
J>>>Да, действительно, твоя правда. Тогда это дефект стандарта, имхо. EP>>Да, похоже на дефект. Точнее зависит от того, "что же хотел сказать автор". EP>>Может они и имели ввиду, что код ТС неверен (просто без диагностики), а оговорка в operator() избыточна. J>Ну, имхо, такой код должен работать без проблем, так что, скорее всего, все-таки дефект.
Согласен — не вижу смысла вводить такое ограничение.
J>Да я так и понял. Просто по стандарту (N3797) получается, что этот код вообще неверен уже на этапе требований к аргументу конструктора, независимо от того, что там дальше происходит.
Да, просто я требования к аргументу конструктора не смотрел, а сразу operator().