2016-03-07 4 views
17

Die folgende versagt sowohl gcc und KlirrenKann ich einen Funktionstyp schreiben, der eine Funktion zurückgibt?

#include <type_traits> 

int foo(); 

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

Der Fehler auf beiden Compiler befasst sich mit der Rechtswidrigkeit der Deklaration einer Funktion, die einen Funktion zu kompilieren. Aber ich deklariere eine solche Funktion nicht - ich versuche nur seinen Typ zu schreiben - da erwartet das result_of. Ist das wirklich noch schlecht gebildet?

+8

Ich denke, dass dies "Der Fehler auf beiden Compiler behandelt die Illegalität der Deklaration einer Funktion, die eine Funktion zurückgibt." würde sinnvollerweise durch den eigentlichen Fehler ersetzt werden – Guiroux

+4

Warum verwenden Sie nicht einfach 'declltype (foo())'? – StenSoft

+3

Sie dürfen keinen Funktionstyp bilden, bei dem die Funktion einen anderen Funktionstyp zurückgibt. "Funktionen dürfen keinen Rückgabetyp von Typ Array oder Funktion haben" dcl.fct/8 – Simple

Antwort

10

Sie vorbei ein Typ-ID, die in [dcl.name] als

[...] syntaktisch eine Erklärung für eine Variable oder Funktion dieses Typs definiert ist, der den Namen des Unternehmens lässt. [...] Es ist möglich, den Ort eindeutig im abstrakten Deklarator zu identifizieren, wo der Bezeichner erscheinen würde, wenn die Konstruktion ein Deklarator in einer Deklaration wäre. Der benannte Typ ist dann derselbe wie der Typ der hypothetischen Kennung .

Damit der hypothetische Bezeichner einen Typ hat, muss die hypothetische Deklaration in erster Linie wohlgeformt sein. Aber es ist nicht nach [dcl.fct]/10. Daher ist das Programm schlecht ausgebildet (und die Fehlermeldungen der Compiler sind tatsächlich verständlich). Dieser Fall wird auch direkter von [temp.deduct]/(8.10) abgedeckt, was impliziert, dass dies ein (SFINAE-freundlicher) Fehler ist.


In der Tat reicht die bloße Angabe eines ungültigen Typs Verwendung, um das Programm schlecht zu machen. Z.B. den Typ Zeiger zu schaffen Funktion Funktion Rückkehr ist schlecht gebildet:

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

So ist die folgende:

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

(Clang sollte dies nicht Cf GCC werden akzeptieren Fehler 17232 ‚s interessante Diskussion.) .

+1

Ich mag diese ael.is Sache wirklich. – Barry

Verwandte Themen