Uma função sobrecarregada deve receber os dois functores, dado que o tipo de lambda é decidível (pode ser convertido em um std::function
(por favor, me corrija se estiver errado) .A pergunta é: por que há um erro de compilação abaixo, apesar de o tipo lambda ser explicitamente definido? ( [&]() -> Type {}
)
Observe que, para a minha solução atual, preciso da captura por referência; é por isso que o código contém a lógica para isso.
O exemplo a seguir descreve o problema:
#include <iostream>
#include <string>
#include <functional>
void do_some(std::function<void(int)> thing)
{
thing(5);
}
void do_some(std::function<bool(int)> thing)
{
if (thing(10))
{
std::cout << "it's true!" << std::endl;
}
}
int main()
{
int local_to_be_modified = 0;
do_some(
[&](int in)
{
local_to_be_modified = in;
std::cout << "This is void-" << std::endl;
}
);
do_some(
[&](int in) -> bool
{
// error: call to 'do_some' is ambiguous
local_to_be_modified += in;
std::cout << "This is bool-" << std::endl;
return true;
}
);
}
c++
c++11
lambda
implicit-conversion
std-function
David Tóth
fonte
fonte
std::function<void(int)>
pode ser construído mesmo a partir de um lambda que retorna algo (que faz com que o valor de retorno seja ignorado).Respostas:
Como a segunda expressão lambda retornada
bool
pode ser convertida em ambosstd::function<void(int)>
estd::function<bool(int)>
implicitamente.std::function
possui um construtor de conversão:Como a definição de Callable ,
Observe que o segundo retorno lambda
bool
, para ostd::function<void(int)>
, como mostrado acima,static_cast<void>(INVOKE(f, t1, t2, ..., tN))
é uma expressão válida (o retornobool
é apenas convertido emvoid
). Em seguida, também pode converterstd::function<void(int)>
implicitamente e causa o problema de ambiguidade.fonte
Você pode explicitamente
static_cast
o lambda para o tipo apropriadoOu armazene o lambda no
std::function<bool(int)>
tipo apropriado e passe para a função (sedo_some(lmda)
for chamado várias vezes)Ou como o @MaxLanghof sugeriu, simplesmente construa a
std::function<bool(int)>
partir do lambda em movimentofonte
static_cast
e apenas construir umstd::function
diretamente a partir dele. É tudo o que acontece durante a conversão implícita.static_cast<
último>
e ele fará a mesma coisa, mas com menos digitação. Não precisa de mais linhas nem nada. godbolt.org/z/fQTqF4