2014-12-15 12 views
8

würde Ich mag, dies zu tun:Wie erstelle ich einen Alias ​​für einen noexcept Funktionszeiger?

using function_type = void (*)(void*)noexcept; 

aber ich erhalte eine Fehlermeldung „Exception-Spezifikationen nicht in Typ-Aliasnamen sind nicht zulässig.“ (Klirren in der Version 6.1 von Xcode)

Gibt es eine Abhilfe einen Alias ​​mit einem noexcept Spezifizierer zu schaffen?

Ich bin auf der Suche nach etwas, das durch die Sprache (keine Erweiterung) für plattformübergreifende Funktionen wie definiert arbeitet.

+1

g ++ kompiliert es gut. Vielleicht ignoriert es einfach den Spezifizierer ... – DarioP

+1

GCC ist hier nicht standardkonform. Clang ist richtig. – Columbo

+1

Hm, es ist ein seltsamer gcc-Bug. Ut akzeptiert keine typedef, akzeptiert aber 'using'. –

Antwort

9

Der Standard verbietet ausdrücklich eine Ausnahme-Spezifikation in einem typedef oder eines Pseudonyms gestattet Erklärung angezeigt wird. Es besagt jedoch auch, dass der Ausnahmespezifizierer möglicherweise in einem Funktionszeigertyp angezeigt wird.

§15.4/2[except.spec]

An exception-specification shall appear only on a function declarator for a function type, pointer to function type, reference to function type, or pointer to member function type that is the top-level type of a declaration or definition, or on such a type appearing as a parameter or return type in a function declarator. An exception-specification shall not appear in a typedef declaration or alias-declaration.

Und wenn ein Zeiger auf Funktion eine Ausnahme-Spezifikation hat, dann muss die Funktionszeiger immer eine Funktion zugeordnet werden, der eine hat kompatible Ausnahmespezifikation

§15.4/5

... A similar restriction applies to assignment to and initialization of pointers to functions, pointers to member functions, and references to functions: the target entity shall allow at least the exceptions allowed by the source value in the assignment or initialization. ...

diese beide verwenden, können Sie die noexcept Spezifikation in den Funktionszeigertyp in einer Kreisverkehr Art und Weise bekommen.

void (*foo_ptr)(void *) noexcept = nullptr; 
using function_type = decltype(foo_ptr); 

Jetzt können Sie nicht eine Funktion ohne noexcept(true) Spezifikation auf einen Funktionszeiger vom Typ function_type zuweisen. clang will fail to compile der Code mit dem Fehler

error: target exception specification is not superset of source

+1

Irgendeine Idee, was die Begründung für diese Einschränkung ist? – kec

+0

Ich denke nicht, §15.4/4 beschäftigt sich mit Zuweisung oder Initialisierung. Sie wollen wahrscheinlich den zweiten Absatz von §15.4/5. –

+0

@kec Meine Vermutung ist, die Exception-Spezifikation als Teil des Funktionstyps zu vermeiden. – Praetorian

3

Eine Alternative zu Praetorian Antwort, die beinhaltet nicht die Deklaration einer Variablen:

void unused_function(void*)noexcept; 
using function_type = decltype(&unused_function); 

Die unused_function deklariert, aber nicht definiert.