2016-01-13 9 views
15

Zwykle lambda C++ bez przechwytywania should be convertable do wskaźnika funkcji w stylu c. W jakiś sposób przekonwertowanie go za pomocą std::function::target nie działa (tzn. Zwraca wartość nullptr), ale także target_type nie pasuje do typu podpisu, mimo że wygląda na to samo.Captureless lambda nie może zostać przekonwertowany na wskaźnik funkcji, gdy jest przechowywany w std :: function

Testowane na VC13 i GCC 5,3/5.2.0/4,8

minimalna przykład badania:

#include <functional> 
#include <iostream> 

void Maybe() { 

} 

void callMe(std::function<void()> callback) { 
    typedef void (*ftype)(); 
    std::cout << (callback.target_type() == typeid(ftype)) << std::endl; 
    std::cout << callback.target<ftype>() << std::endl; 
} 

int main() { 
    callMe([]() {}); 
    callMe(Maybe); 
} 

oczekiwany wynik byłby

1 
<address> 
1 
<address> 

rzeczywista moc

0 
0 
1 
<address> 

Pytanie brzmi: dlaczego znak lambda różni się od funkcji przekazanej?

+0

_ "... powinien być convertable do a ..." _ - wymagany cytat. – Useless

+4

@Useless Hmmm, [cytat jest tutaj] (http://stackoverflow.com/a/28746827/1413395). –

+0

@ πάνταῥεῖ dzięki, zawarłem to w pytaniu –

Odpowiedz

15

Podczas pierwszego połączenia, std::function nie przejmuje się rozkładaniem lambda na wskaźnik, tylko przechowuje go, z jego rzeczywistym typem (który w rzeczywistości nie jest void()).

Można wymusić lambda na próchnicę do wskaźnika przed tworzącego std::function ze ten ostatni po prostu za pomocą jednoskładnikowa +:

callMe(+[](){}); 
// ^
+4

+1, Ale: I * naprawdę * nie lubię tego '+' hacka na integrację typu wskaźnik/wskaźnik. Po prostu przesłania to intencje zbyt wiele. Lepiej to wyrazić, zawijając to w dedykowaną funkcję. –

+0

Znaleźliśmy dupek [tego pytania i odpowiedzi] (http://stackoverflow.com/questions/18889028/a-positive-lambda-what-sorcery-is-this/18889029?s=1|0.0000#18889029)? –

+0

@ πάνταῥεῖ Nie są one dokładnie duplikatami (pozostałe dotyczą dedukcji typu i rozdzielczości przeciążenia), ale w rzeczywistości są dość mocno powiązane. – Quentin

Powiązane problemy