todas sirve significa que para lenguaje las funciones comando c++ c++11 return-type std-function

c++ - sirve - Usando `std:: function<void(...)>` para llamar a la función no-vacía



return 0 lenguaje c (3)

Parece que puede estar bien para funciones anónimas.

Cita de http://www.alorelang.org/release/0.5/doc/std_function.html (esto no es de la biblioteca estándar de C ++, sin embargo, parece que están usando algo similar en sus enlaces a C ++)

Los objetos de función solo se pueden crear con una definición de función, una expresión de función anónima o accediendo a un método vinculado utilizando el operador de punto (.).

Otra manera en que esto podría hacerse es almacenando el puntero de función en automático como se ve aquí: http://en.wikipedia.org/wiki/Anonymous_function (sección de C ++)

Hace un tiempo utilicé std::function o menos así:

std::function<void(int)> func = [](int i) -> int { return i; };

Básicamente, hice esto porque quería almacenar diferentes objetos de función en una std::function , pero no quería restringir los tipos de devolución de estas funciones. Como esto parecía funcionar, lo hice. Pero no estoy convencido de que sea seguro de usar, y no he podido encontrar ninguna documentación al respecto. ¿Alguien sabe si este uso es legítimo? O, en términos más generales, ¿cuáles son las reglas para el objeto que se pueden asignar de forma segura a una std::function ?

Editar

Para aclarar, el problema que me preocupa es que la función lambda devuelve un int , mientras que func se declara con el tipo de retorno void . No estoy seguro de si esto está bien, especialmente una vez que se realiza una llamada a func() .


Su caso de uso está bien definido de acuerdo con el estándar.

Está construyendo una std::function partir de un objeto invocable [1]

§20.8.11.2.1 / 7:

template<class F> function(F f);

Requiere: F debe ser CopyConstructible. f debe ser invocable (20.8.11.2) para tipos de argumentos ArgTypes y devolver tipo R.

Entonces, ¿se puede llamar tu f?

§20.8.11.2 / 2 dice:

Un objeto invocable f de tipo F es invocable para tipos de argumentos ArgTypes y devuelve tipo R si la expresión INVOKE (f, declval<ArgTypes>()..., R) , considerada como un operando no evaluado (cláusula 5), ​​es bien formado (20.8.2).

Y la definición de INVOKE dice:

§20.8.2

  1. Defina INVOKE (f, t1, t2, ..., tN) siguiente manera: ... cosas relacionadas con la función miembro / var punteros ... - f(t1, t2, ..., tN) en todos los demás casos.

  2. Defina INVOKE (f, t1, t2, ..., tN, R) as INVOKE (f, t1, t2, ..., tN) convertido implícitamente a R

Y dado que cualquier tipo puede convertirse implícitamente en void , su código debería estar bien con un compilador que cumpla con los estándares. Como se señala a continuación, no hay una conversión implícita a vacío, por lo que no está bien definido.

[1]: Creo que el lambda cuenta como un objeto invocable aquí, aunque no tengo una referencia para eso. Su lambda también podría usarse como un puntero a la función ya que no captura el contexto


Tu código tiene un comportamiento indefinido. Puede o no funcionar como espera. La razón por la cual tiene un comportamiento indefinido es debido a 20.8.11.2.1 [func.wrap.func.con] / p7:

Requiere: F debe ser CopyConstructible . f debe ser invocable (20.8.11.2) para tipos de argumentos ArgTypes y return type R

Para que f pueda llamar para el tipo de devolución R , f debe devolver algo implícitamente convertible al tipo de devolución de la std::function ( void en su caso). Y int no es implícitamente convertible en void .

Esperaría que tu código funcione en la mayoría de las implementaciones. Sin embargo, en al menos una implementación ( libc ++ ), no se puede compilar:

test.cpp:7:30: error: no viable conversion from ''int (int)'' to ''std::function<void (int)>'' std::function<void(int)> ff = f; ^ ~

Irónicamente, la razón de este comportamiento proviene de otra pregunta SO .

La otra pregunta presentaba un problema con el uso de std::function . La solución a ese problema implicó que la implementación aplicara la cláusula Requires: en tiempo de compilación. En contraste, la solución al problema de esta pregunta está prohibiendo a la implementación aplicar la cláusula Requires: