Przeciążona funkcja powinna przyjmować oba funktory, biorąc pod uwagę, że typ lambda jest rozstrzygalny (można ją wyrzucić std::function
(proszę poprawić mnie, jeśli się mylę). Pytanie brzmi: Dlaczego poniżej jest błąd kompilacji, mimo że jawnie jest to typ lambda zdefiniowany? ( [&]() -> Type {}
)
Pamiętaj, że dla mojego obecnego rozwiązania potrzebuję przechwytywania przez referencję, dlatego kod zawiera logikę.
Poniższy przykład opisuje problem:
#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
źródło
źródło
std::function<void(int)>
można go zbudować nawet z lambda, które coś zwraca (co powoduje, że zwracana wartość jest ignorowana).Odpowiedzi:
Ponieważ 2. zwracane wyrażenie lambda
bool
może zostać przekonwertowane na obastd::function<void(int)>
istd::function<bool(int)>
niejawnie.std::function
ma konstruktor konwertujący:Jako definicja Callable ,
Zauważ, że drugi zwracany lambda
bool
, dlastd::function<void(int)>
, jak pokazano powyżej,static_cast<void>(INVOKE(f, t1, t2, ..., tN))
jest prawidłowym wyrażeniem (zwracanybool
jest właśnie konwertowany navoid
). Następnie może również przekształcić się wstd::function<void(int)>
sposób domyślny i powodować problem niejednoznaczności.źródło
Możesz jawnie
static_cast
lambda do właściwego typuLub zapisz lambda do odpowiedniego
std::function<bool(int)>
typu i przekaż do funkcji (jeślido_some(lmda)
powinna być wywoływana wiele razy)Lub, jak sugerował @MaxLanghof , po prostu buduj
std::function<bool(int)>
z lambda w drodzeźródło
static_cast
i po prostu zbudowaćstd::function
bezpośrednio z niego. To wszystko dzieje się podczas niejawnej konwersji.static_cast<
i trwać>
i zrobi to samo, ale przy mniejszym pisaniu. Nie potrzebuje więcej linii ani nic. godbolt.org/z/fQTqF4