Eine überladene Funktion sollte beide Funktoren aufnehmen, da der Lambda-Typ entscheidbar ist (umsetzbar auf einen std::function
(bitte korrigieren Sie mich, wenn ich falsch liege). Die Frage ist: Warum gibt es unten einen Kompilierungsfehler, obwohl der Lambda-Typ explizit ist definiert? ( [&]() -> Type {}
)
Bitte beachten Sie, dass ich für meine aktuelle Lösung die Erfassung als Referenz benötige. Deshalb enthält der Code die Logik dafür.
Das folgende Beispiel beschreibt das 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
quelle
quelle
std::function<void(int)>
kann sogar aus einem Lambda konstruiert werden, das etwas zurückgibt (wodurch der Rückgabewert ignoriert wird).Antworten:
Weil der 2. Lambda-Ausdruck, der zurückkehrt
bool
, in beidestd::function<void(int)>
undstd::function<bool(int)>
implizit konvertiert werden könnte .std::function
hat einen konvertierenden Konstruktor:Wie die Definition von Callable ,
Beachten Sie, dass das 2. Lambda
bool
, das für das zurückgegeben wirdstd::function<void(int)>
, wie oben gezeigt,static_cast<void>(INVOKE(f, t1, t2, ..., tN))
ein gültiger Ausdruck ist (das zurückgegebenebool
wird nur in konvertiertvoid
). Dann könnte es auchstd::function<void(int)>
implizit in konvertieren und das Mehrdeutigkeitsproblem verursachen.quelle
Sie können
static_cast
das Lambda explizit auf den richtigen Typ einstellenOder speichern Sie das Lambda im richtigen
std::function<bool(int)>
Typ und übergeben Sie es an die Funktion (fallsdo_some(lmda)
dies mehrmals aufgerufen werden sollte).Oder wie @MaxLanghof vorschlug, einfach unterwegs
std::function<bool(int)>
aus Lambda zu konstruierenquelle
static_cast
und einfach einstd::function
direkt daraus erstellen. Das ist sowieso alles, was während der impliziten Konvertierung passiert.static_cast<
und das letzte entfernen können>
und es das gleiche tun wird, aber mit weniger Eingabe. Es braucht keine weiteren Zeilen oder so. godbolt.org/z/fQTqF4