Operatore freccia (->) nell'intestazione della funzione


128

Mi sono imbattuto nel seguente codice:

template <typename T, typename T1> auto compose(T a, T1 b) -> decltype(a + b) {
   return a+b;
}

C'è una cosa che non riesco a capire:

Dove posso scoprire cosa significa l'operatore freccia ( ->) nell'intestazione della funzione? Immagino puramente logicamente che l' ->operatore determini un tipo a cui autoverrà dedotto, ma voglio chiarirlo. Non riesco a trovare alcuna informazione.


2
Fa parte della sintassi del tipo di ritorno finale. Vedi stackoverflow.com/a/4113390/962089
chris

2
Non è un operatore ma una parte della sintassi.
texasbruce,

1
In risposta a "dove posso leggere?", La specifica C ++ è la più autorevole. In mancanza di fondi o desiderio di spendere $$, l'ultima bozza di lavoro è spesso abbastanza vicina e senza costi. Queste specifiche sono altamente tecniche, quindi non hanno familiarità con la lettura delle specifiche ISO, prova cplusplus.com o cppreference.com o altri siti simili che non sono autorevoli, ma di solito sono molto precisi. Nota: il tipo di ritorno finale può essere omesso a partire da C ++ 14.
Les

Risposte:


205

In C ++ 11, ci sono due sintassi per la dichiarazione di funzione:

    dichiarazioni- argomento dell'identificatore del tipo di ritorno ( ... )

e

    auto identificatore ( argomento-dichiarazioni ... ) -> return_type

Sono equivalenti. Ora, quando sono equivalenti, perché mai vuoi usare quest'ultimo? Bene, C ++ 11 ha introdotto questa decltypecosa interessante che ti consente di descrivere il tipo di espressione. Quindi potresti voler derivare il tipo restituito dai tipi di argomento. Quindi provi:

template <typename T1, typename T2>
decltype(a + b) compose(T1 a, T2 b);

e il compilatore ti dirà che non sa cosa ae bsono decltypenell'argomento. Questo perché sono dichiarati solo dalla lista degli argomenti.

È possibile aggirare facilmente il problema utilizzando declvale i parametri del modello già dichiarati. Piace:

template <typename T1, typename T2>
decltype(std::declval<T1>() + std::declval<T2>())
compose(T1 a, T2 b);

tranne che sta diventando davvero prolisso ora. Quindi la sintassi della dichiarazione alternativa è stata proposta e implementata e ora è possibile scrivere

template <typename T1, typename T2>
auto compose(T1 a, T2 b) -> decltype(a + b);

ed è meno dettagliato e le regole di scoping non hanno bisogno di cambiare.


Aggiornamento C ++ 14: C ++ 14 consente anche solo

    auto identificatore ( argomento-dichiarazioni ... )

purché la funzione sia completamente definita prima dell'uso e tutte le returnistruzioni deducano allo stesso tipo. La ->sintassi rimane utile per le funzioni pubbliche (dichiarate nell'intestazione) se si desidera nascondere il corpo nel file di origine. Un po 'ovviamente che non può essere fatto con i template, ma ci sono alcuni tipi concreti (di solito derivati ​​dalla metaprogrammazione dei template) che sono difficili da scrivere altrimenti.


2
risposta molto buona, ordinata e istruttiva @ Jan Hudec. Pollici in su. C'è qualcosa di cambiato C++14mentre uso autoper returndigitare in tale funzione senza la necessità della -> decltype(a + b)parte. Ormai è ridondante o ha altri casi in cui dovrebbe ancora essere usato? o è un'estensione specifica del compilatore?
Shadi,

1
@Shadi, C ++ 14 include N3638 , che consente di dedurre il tipo di ritorno dichiarato come auto, senza ->notazione, purché la funzione sia completamente definita prima dell'uso e tutte le returnistruzioni deducano allo stesso tipo. La ->notazione è ancora utile se si desidera utilizzare la detrazione per la funzione pubblica nascondendo il corpo nel file di origine.
Jan Hudec,

23

In parole povere indica che il tipo restituito è il tipo inferito della somma di ae b.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.