2015-06-11 34 views
8

Ho una piccola funzione lambda che trova e restituisce un QTreeWidgetItem. Ma se non trova l'articolo dato, restituirà un nullptr. Ma se provo a compilarlo, allora mi dà un errore.Come restituire nullptr da una funzione lambda?

La funzione:

auto takeTopLevelItem = [](QTreeWidget* aTreeWidget, const QString& aText) 
{ 
    const int count = aTreeWidget->topLevelItemCount(); 
    for (int index = 0; index < count; ++index) 
    { 
     auto item = aTreeWidget->topLevelItem(index); 
     if (item->text(0) == aText) 
     { 
      return aTreeWidget->takeTopLevelItem(index); 
     } 
    } 
    return nullptr; // This causes a compilation error. 
}; 

L'errore:

Error 1 error C3487: 'nullptr': all return expressions in a lambda must have the same type: previously it was 'QTreeWidgetItem *' cpp 251

ho cambiato la linea indicata con questo e ora compila:

return (QTreeWidgetItem*)(nullptr); 

ma vorrebbe evitare questo sintassi. Come posso risolvere questo ?

Io uso Visual Studio 2012.

+0

Questo sembra un bug in VS2012? – Yakk

+0

@Yakk: perché? Il messaggio di errore è abbastanza chiaro, non è vero? – MSalters

+0

@MSalters Hmm. Strano, in realtà pensavo che fintanto che i successivi tipi di ritorno sono compatibili (implicitamente convertibili) al primo tipo di ritorno, tutto era a-ok. – Yakk

risposta

11

È possibile aggiungere un esplicito tipo di ritorno della nota:

auto takeTopLevelItem = [](...) -> QTreeWidgetItem* 
{ 
    // ... 
} 

In questo modo nullptr verrà convertito correttamente nel tipo di puntatore. Stai ricevendo quell'errore perché lambda non si assume alcuna conversione e considera nullptr_t come un tipo di ritorno alternativo legittimo.


Come nota a margine, considerare invece l'utilizzo di (std::)optional. Il nullability dei puntatori può essere utilizzato per rappresentare un ritorno mancante, ma non significa necessariamente che debba esserlo.

+4

Non sono d'accordo con l'ultimo punto riguardante 'opzionale': la maggior parte delle cose in' Qt' è passata da puntatori, e credo che il risultato di questo lambda sia passato da qualche parte a 'Qt'. Inoltre, è meglio seguire il loro stile, anche se potrebbe essere malvagio nel moderno C++. – lisyarus

+1

@lisyarus Quindi * considerare *.Non deve necessariamente avere senso in questo particolare esempio, ma può essere un'opzione per un altro lettore. –

+0

Considera di rimuovere l'ultimo commento sull'uso di 'std :: optional' invece di restituire un nullptr. Non penso che la tua risposta sia migliore. La parte superiore è semplicemente perfetta. –

2

Se si desidera solo per evitare la sintassi, piuttosto che la fusione, si potrebbe in questo modo:

static_cast<QTreeWidgetItem*>(nullptr); 

ho fatto un piccolo esempio di come Bartek e di risposta della miniera funzionano davvero:

#include <iostream> 

class A { 
    int a; 
}; 

auto bla = [] (A* obj, bool flag) -> A* { 
    if(flag) 
    return obj; 
    return nullptr; 
// return static_cast<A*>(nullptr); 
}; 

int main() { 
    A obj; 
    A* ptr = &obj; 
    bool flag = false; 
    if(bla(ptr, flag) == nullptr) 
    std::cout << "ok\n"; 
    return 0; 
} 
+1

Perché * non dovrebbe * compilare il tuo esempio? La struttura dei parametri può essere omessa interamente, lasciando un lambda il cui tipo restituito è * solo * 'nullptr_t'. –

+0

La tua risposta è molto meglio @BartekBanachewicz. Cancellando il mio e dandoti un +1. – gsamaras

+0

La tua osservazione 'static_cast' era perfettamente soddisfacente. –

Problemi correlati