Me preguntaba cómo comprobar correctamente si un std::functionestá vacío. Considere este ejemplo:
class Test {
std::function<void(int a)> eventFunc;
void registerEvent(std::function<void(int a)> e) {
eventFunc = e;
}
void doSomething() {
...
eventFunc(42);
}
};
Este código se compila bien en MSVC, pero si llamo doSomething()sin inicializar eventFuncel código obviamente se bloquea. Eso es lo esperado, pero me preguntaba cuál es el valor de eventFunc? El depurador dice 'empty'. Así que lo arreglé usando una simple declaración if:
void doSomething() {
...
if (eventFunc) {
eventFunc(42);
}
}
Esto funciona, pero todavía me pregunto cuál es el valor de no inicializado std::function. Me gustaría escribir if (eventFunc != nullptr)pero std::function(obviamente) no es un puntero.
¿Por qué el puro si funciona? ¿Cuál es la magia detrás de esto? Y, ¿es la forma correcta de comprobarlo?
c++
c++11
std-function
NightElfik
fuente
fuente

eventFuncno es una lambda; es unstd::function. Puede almacenar lambdas enstd::functions, pero no son lo mismo.Respuestas:
No está comprobando una lambda vacía, sino si
std::functiontiene un objetivo invocable almacenado en él. La verificación está bien definida y funciona, por lostd::function::operator boolque permite la conversión implícitaboolen contextos donde se requieren valores booleanos (como la expresión condicional en unaifdeclaración).Además, la noción de una lambda vacía realmente no tiene sentido. Detrás de escena, el compilador convierte una expresión lambda en una
struct(oclass) definición, con las variables capturadas almacenadas como miembros de datos de estastruct. También se define un operador de llamada de función pública, que es lo que le permite invocar la lambda. Entonces, ¿qué sería una lambda vacía?También puede escribir
if(eventFunc != nullptr)si lo desea, es equivalente al código que tiene en la pregunta.std::functiondefineoperator==yoperator!=sobrecarga para comparar con anullptr_t.fuente
== nullptrPero no hace lo mismo? Parece que se supone que hay una sobrecarga para el==operador que causa un "vacío"std::functionpara comparartrueconnullptr: cplusplus.com/reference/functional/function/operatorsnullptrfuncionará también,if(eventFunc != nullptr)es equivalente aif(eventFunc)en la pregunta anterior.std::function::operator boolno permite la conversión implícita abool.explicitDespués de todo, está marcado , pero el estándar hace una excepción para ciertas construcciones de lenguaje que esperan expresiones booleanas, llamándolo "convertido contextualmente a bool". Puede encontrar el fragmento relevante de standardese y una explicación aquí: chris-sharpe.blogspot.com/2013/07/…explicit, por eso tuve cuidado de indicar que permite la conversión implícitaboolen contextos donde se requieren valores booleanos . Esto es exactamente lo que sucede en el código en cuestión.Consulte aquí http://www.cplusplus.com/reference/functional/function/operator_bool/
Ejemplo
Salida
fuente
swap(). Estaba pensando que la salida estaba al revés hasta que me di cuenta.(Déjame darte una respuesta clara).
Puede comprobar si a
std::functionestá vacío constd::function::operator bool.Ejemplo
Salida
fuente