¿Es ilegal invocar una función std:: bajo el estándar?
Todas las citas son de N3797.
4/3 [conv]
Una expresión e puede ser convertido implícitamente a un tipo T si y solo si la declaración T t = e; está bien formado, para algunas variables temporales inventadas t
Esto implica que ninguna expresión puede convertirse implícitamente a void
, ya que void t=e
es ilegal para todas las expresiones e
. Esto es incluso cierto si e
es una expresión de tipo void
, como void(3)
.
So una expresión de tipo void
no se puede convertir implícitamente void
.
Que nos lleva a: {[27]]}
20.9.2/2 Requisitos [func.requerir]
Definir INVOCAR (f, t1, t2, ..., tN, R) como INVOCAR (f, t1, t2, ..., tN) convertido implícitamente a R .
En resumen, INVOKE(f, t1, t2, ..., tN, R)
nunca es válido cuando R
es void
, ya que nada (incluido void
) se puede convertir implícitamente a void
.
Como resultado de esto, todos std::function<void(Args...)>
tienen la propiedad !*this
y por lo tanto no se puede llamar, ya que los únicos constructores que no tienen !*this
como postcondición (o no copian dicho estado de otro function
del mismo tipo) requieren Callable
de uno de los parámetros.
20.9.11.2/7 plantilla de Clase función [func.envolver.func]
Requiere: F será CopyConstructible . f será Exigible ( 20.9.11.2 ) para tipos de argumentos ArgTipos y tipo de retorno R . El constructor de copia y destructor de Un no lanzará excepciones.
20.9.11.2/2 plantilla de Clase función [func.envolver.func]
Un objeto invocable f de tipo F ser Invocable para tipos de argumentos ArgTipos y tipo de retorno R si la expresión- sion INVOCAR (f, declval ()..., R) , considerado como un operando no evaluado (Cláusula 5 ), está bien formar ( 20.9.2 ).
Como se demostró anteriormente, no hay Callable
expresiones para std::function<void(Args...)>
.
Si de alguna manera se encontrara tal std::function<void(Args...)>
, invocar operator()
estaría mal formado:
Invocación [func .envolver.func.inv]
Efectos: INVOCAR (f, std:: forward (args)..., R) ( 20.9.2 ), donde f es el objetivo ob- ject ( 20.9.1 ) de *este .
Como INVOKE(f, std::forward<ArgTypes>(args)..., void)
está mal formado para todos los argumentos y f
.
¿Es correcta esta línea de razonamiento?
1 answers
Sí, su análisis es correcto; llegué a la misma conclusión aquí.
Según Daniel Kruegler, este problema debería aparecer en la lista de defectos de la biblioteca después del siguiente correo:
Ya se ha enviado un problema de biblioteca correspondiente, pero no aún visible en la lista de problemas.
Esperemos que una vez que se haga visible también tendremos una respuesta concluyente a si es permisible construir un std::function
con signature returning void
pasando un callable con signature returning non-void ( Usando `std::function
Actualización: esto se introdujo como LWG 2420, que se resolvió a favor de special-casing void
return type to static_cast
el resultado de la función invocada a void
. Esto significa que un no-void
retornable puede ser el objetivo de un std::function<void(...)>
. LWG2420 se aplicó como corrección post-publicación a C++14; mientras tanto, todos los compiladores que conozco aplican efectivamente este comportamiento como una extensión en el modo C++11.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:14:57