2016-06-05 11 views
5

std::function permette di fare questo:Perché la funzione non impedisce la costruzione da un tipo di ritorno diverso?

std::function<void()> = []()->int{return 42;}; 

Ma non questa:

std::function<void()> = [](int i)->int{return 42;}; 

Presumibilmente perché il tipo di ritorno non è parte della firma di una funzione. Ma std::function è un tipo di classe che ha un tipo restituito e conosce il tipo di ritorno dell'oggetto funzione da cui è stato costruito. Quindi c'è una possibilità di un errore del compilatore qui.

Perché non c'è un errore del compilatore?

+1

Anche il tuo codice ha un comportamento non definito. –

+0

@sleeptightpupper: Non è un duplicato del primo, poiché il primo riguarda i parametri, non i tipi di ritorno diversi. –

+0

@NicolBolas È sicuramente un [duplicato] (http://stackoverflow.com/a/9341064). Il corto di esso è 'int' non è implicitamente convertibile in' void' quindi otteniamo un comportamento indefinito. – user6412786

risposta

4

C'era un bug in the C++11 standard che ha reso tutto inutilizzabile il std::function<void(???)>. Alcuni compilatori hanno interpretato il bug per indicare che il tipo di ritorno di qualsiasi cosa memorizzata in tale std::function dovrebbe essere ignorato, altri che solo vuoto era compatibile con tale std::function.

Nel defect resolution (tramite @ t.c) è stato corretto in modo che un std::function<void(???)> ignori il tipo di ritorno (e il valore) dell'oggetto archiviato.

Il compilatore sta utilizzando quell'interpretazione, che è quella corrente.

Indipendentemente da ciò, gli argomenti devono essere convertiti dagli argomenti dello std::function.

In breve, perché lo standard (revisionato) lo dice.

In pratica, è utile poter scartare i valori di ritorno. Nel frattempo, non è possibile richiamare una funzione o un oggetto callable senza dati per invocarla. È stato deciso che la corrispondenza imperfetta è ok (quindi, se gli argomenti/valori di ritorno vengono convertiti, std::function è il gioco). E il gioco è fatto.

Problemi correlati