2014-12-15 21 views
8

Chciałbym to zrobić:Jak utworzyć alias dla wskaźnika funkcji noexcept?

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

Ale pojawia się błąd „specyfikacje wyjątek nie są dozwolone w typie aliasów”. (w wersji 6.1 kodu Xcode)

Czy istnieje sposób na utworzenie aliasu ze specyfikatorem noexcept?

Szukam czegoś, co działa zgodnie z definicją języka (a nie rozszerzeniem) dla różnych platform.

+1

g ++ kompiluje to dobrze. Może to po prostu ignoruje specyfikator ... – DarioP

+1

GCC nie jest tutaj zgodny z normą. Clang jest poprawny. – Columbo

+1

Hm, to dziwny błąd w gcc. Ut nie akceptuje typedef, ale akceptuje 'using'. –

Odpowiedz

9

Standardowo jawnie zabrania specyfikacji wyjątku pojawiania się w typedef lub deklaracji aliasu. Ale stwierdza również, że specyfikator wyjątku może pojawić się w typie wskaźnika funkcji.

§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.

Jeśli wskaźnik do funkcji posiada specyfikację wyjątku, to wskaźnik funkcji muszą być zawsze przypisany typ funkcji, które ma zgodna specyfikacja wyjątków.

§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. ...

Korzystanie z tych dwóch, można uzyskać specyfikację do funkcji typu wskaźnika w sposób okrężny noexcept.

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

Teraz nie można przypisać funkcję bez noexcept(true) specyfikacji do wskaźnika funkcji typu function_type. clang will fail to compile kod z błędem

error: target exception specification is not superset of source

+1

Czy masz pojęcie, jakie jest uzasadnienie tego ograniczenia? – kec

+0

Nie sądzę, że § 15.4/4 dotyczy przypisania lub inicjowania. Prawdopodobnie chcesz, aby akapit drugi w § 15.4/5. –

+0

@kec Domyślam się, że unikam specyfikacji wyjątków jako części typu funkcji. – Praetorian

3

Alternatywą do odpowiedzi pretorianów, która nie wymaga deklarowania zmiennej:

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

unused_function została zadeklarowana, ale nie zdefiniowane.