Нельзя ли ссылаться на std:: function <void (Args...)> по стандарту?
Все цитаты из N3797.
4/3 [conv]
Выражение е возможно неявно преобразованный к типу T тогда и только тогда, когда декларация T t = e; хорошо сформирована, для некоторой изобретенной временной переменной т
Это означает, что выражение не может быть неявно преобразовано в void
, поскольку void t=e
является незаконным для всех выражений e
. Это даже верно, если e
является выражением типа void
, например void(3)
.
Таким образом, выражение типа void
не может быть неявно преобразовано в void
.
Это приводит нас к:
20.9.2/2 Требования [func.require]
Define ВЫЗОВ (f, t1, t2,..., tN, R) в виде ВЫЗОВ (f, t1, t2,..., tN) неявно преобразованный в р.
Короче говоря, INVOKE(f, t1, t2, ..., tN, R)
никогда не действует, если R
равно void
, поскольку ничто (включая void
) не может быть неявно преобразовано в void
.
В результате этого все std::function<void(Args...)>
имеют свойство !*this
и поэтому не могут быть вызваны как единственные конструкторы, не имеющие !*this
в качестве постусловия (или не копировать такое состояние из другого function
того же типа) требуют Callable
одного из параметров.
20.9.11.2/7 Шаблон класса
функция
[Func.wrap.func]
Требуется: F должен быть CopyConstructible, е должны быть Подтверждаемыми ( 20.9.11.2 ) для типов аргументов ArgTypes и тип возврата р, Конструктор копирования и деструктор не должны исключать исключения.
20.9.11.2/2 Шаблон класса
функция
[Func.wrap.func]
Вызываемый объект е типа F является подлежащий выкупу для типов аргументов ArgTypes и тип возврата р если выражение Sion ВЫЗОВ (f, declval()..., R), рассматриваемый как неоцениваемый операнд (пункт 5), хорошо сформированный ( 20.9.2).
Как показано выше, для std::function<void(Args...)>
нет выражений Callable
.
Если каким-то образом найденный std::function<void(Args...)>
, где был найден, вызывается operator()
:
вызов [func.wrap.func.inv]
Эффекты: ВЫЗОВ (f, std:: forward (args)..., R) ( 20.9.2), где е является целевым ject ( 20.9.1 ) *это.
как INVOKE(f, std::forward<ArgTypes>(args)..., void)
плохо сформирован для всех аргументов и f
.
Является ли эта линия рассуждения звуком?
Ответы
Ответ 1
Да, ваш анализ правильный; Я пришел к тому же выводу здесь.
По словам Даниэля Крюглера, этот вопрос должен появиться в списке дефектов библиотеки после следующей рассылки:
Соответствующая проблема с библиотекой уже отправлена, но не но видимый в списке проблем.
Надеемся, что когда это станет видимым, мы также получим окончательный ответ на то, можно ли построить std::function
с сигнатурой, возвращающей void
, передавая вызываемый код с возвращаемой сигнатурой не-void (Использование` std:: function < void (...) > `для вызова функции non-void).
Обновление: это было введено как LWG 2420, которое было разрешено в отношении типа возврата void
с особым корпусом static_cast
результат вызываемой функции void
. Это означает, что вызываемым возвращаемым не void
может быть цель std::function<void(...)>
. LWG2420 был применен в качестве поправки после публикации к С++ 14; Между тем, все компиляторы, которые я знаю, эффективно применяют это поведение как расширение в режиме С++ 11.