Eu queria saber como verificar corretamente se um std::function
está vazio. Considere este exemplo:
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 compila perfeitamente no MSVC, mas se eu chamar doSomething()
sem inicializar eventFunc
o código obviamente falha. Isso é esperado, mas eu queria saber qual é o valor do eventFunc
? O depurador diz 'empty'
. Então, resolvi isso usando uma instrução if simples:
void doSomething() {
...
if (eventFunc) {
eventFunc(42);
}
}
Isso funciona, mas ainda estou me perguntando qual é o valor de não inicializado std::function
? Eu gostaria de escrever, if (eventFunc != nullptr)
mas std::function
(obviamente) não é um indicador.
Por que o puro se funciona? Qual é a magia por trás disso? E é a maneira correta de verificar isso?
c++
c++11
std-function
NightElfik
fonte
fonte
eventFunc
não é um lambda; é umstd::function
. Você pode armazenar lambdas emstd::function
s, mas eles não são a mesma coisa.Respostas:
Você não está verificando se há um lambda vazio, mas se
std::function
há um destino que pode ser chamado armazenado nele. A verificação é bem definida e funciona porquestd::function::operator bool
permite a conversão implícitabool
em contextos onde os valores booleanos são necessários (como a expressão condicional em umaif
instrução).Além disso, a noção de um lambda vazio realmente não faz sentido. Nos bastidores, o compilador converte uma expressão lambda em uma definição
struct
(ouclass
), com as variáveis que você captura armazenadas como membros de dados delastruct
. Um operador de chamada de função pública também é definido, o que permite que você invoque o lambda. Então, o que seria um lambda vazio?Você também pode escrever
if(eventFunc != nullptr)
se quiser, é equivalente ao código que você tem na pergunta.std::function
defineoperator==
eoperator!=
sobrecarrega para comparar com anullptr_t
.fonte
== nullptr
faz a mesma coisa? Parece que não é suposto ser uma sobrecarga para o==
operador que provoca um "vazio"std::function
para comparartrue
contranullptr
: cplusplus.com/reference/functional/function/operatorsnullptr
funcionará também,if(eventFunc != nullptr)
é equivalente aif(eventFunc)
na pergunta acima.std::function::operator bool
não permite a conversão implícita embool
.explicit
Afinal, ele está marcado , mas o padrão abre uma exceção para certas construções de linguagem que esperam expressões booleanas, chamando-o de "convertido contextualmente em bool". Você pode encontrar o trecho relevante do standardese e uma explicação aqui: chris-sharpe.blogspot.com/2013/07/…explicit
, é por isso que tive o cuidado de afirmar que permite a conversão implícitabool
em contextos onde os valores booleanos são necessários . Isso é exatamente o que está acontecendo no código em questão.Verifique aqui http://www.cplusplus.com/reference/functional/function/operator_bool/
Exemplo
Resultado
fonte
swap()
. Eu estava pensando que a saída estava ao contrário até que percebi.(Deixe-me dar uma resposta clara.)
Você pode verificar se a
std::function
está vazio comstd::function::operator bool
.Exemplo
Resultado
fonte