2016-03-07 35 views
17

Quanto segue non riesce a compilare su entrambi GCC e clangPosso scrivere un tipo di funzione che restituisce una funzione?

#include <type_traits> 

int foo(); 

int main() 
{ 
    using R = std::result_of_t<decltype(foo)()>; // error 
} 

L'errore su entrambe le offerte compilatori con l'illegalità di dichiarare una funzione che restituisce una funzione. Ma non sto dichiarando una tale funzione - sto solo cercando di scrivere il suo tipo - poiché è ciò che si aspetta result_of. Questo è davvero ancora mal formato?

+8

Penso che questo "L'errore su entrambi i compilatori riguarda l'illegittimità di dichiarare una funzione che restituisce una funzione". sarebbe utilmente sostituito dall'errore effettivo – Guiroux

+4

Perché non usi semplicemente 'decltype (foo())'? – StenSoft

+3

Non è consentito creare un tipo di funzione in cui la funzione restituisce un altro tipo di funzione. "Le funzioni non devono avere un tipo di ritorno di tipo matrice o funzione" dcl.fct/8 – Simple

risposta

10

si sta passando un tipo-id, che è definito in [dcl.name] come

[...] sintatticamente una dichiarazione di una variabile o una funzione di quel tipo che omette il nome dell'entità. [...] È possibile identificare in modo univoco la posizione nel dichiaratore astratto in cui l'identificatore apparirebbe se la costruzione fosse un dichiarante in una dichiarazione. Il tipo named è quindi uguale al tipo dell'identificatore ipotetico .

Per l'identificatore ipotetico di avere un qualche tipo, la dichiarazione ipotetica deve essere ben formata in primo luogo. Ma non è come per [dcl.fct]/10. Quindi il programma è mal formato (e i messaggi di errore dei compilatori sono effettivamente comprensibili). Questo caso è anche più direttamente coperto da [temp.deduct]/(8.10), il che implica che si tratta di un errore (SFINAE-friendly).

Infatti, solo l'utilizzo di un tipo non valido è sufficiente per rendere il programma mal formato. Per esempio. la creazione del tipo puntatore a funzione funzione che restituisce è mal formato:

using f = int(); 
using t = f(*)(); 

Così è la seguente:

struct A {virtual void f() = 0;}; 
using t = A(*)(); 

(Clang non deve essere l'accettazione del presente Cf GCC bug 17232 E' interessante discussione.) .

+1

Mi piace molto questa cosa di eel.is. – Barry

Problemi correlati