2016-02-22 13 views
6

Dire che ho queste dichiarazioni:Casting un puntatore a funzione in una noexcept specificato puntatore a funzione

using fp_type = void(*)(); 
using fp2_type = void(*)() noexcept; 

e

void func(){} 
fp_type fp(func); 

è il cast fp2_type(fp) ben formato? Al contrario (lanciando un puntatore a funzione specificata senza eccezioni in un puntatore a funzione senza un identificatore noex)?

+1

"Il contrario" va bene e in realtà una conversione implicita. 'fp2_type (fp)' sembra che dovrebbe essere un 'reinterpret_cast'. –

+2

Interessante domanda. Nota: * "15.4.12 Una specifica di eccezione non è considerata parte di un tipo di funzione" * –

+0

In realtà, questo è prima o dopo aver reso parte specifica eccezione del sistema di tipi (cioè, è per C++ 1z o C + + 14/precedente)? –

risposta

3

questo è mal formati in C++ 14 e precedenti:

using fp2_type = void(*)() noexcept; 

a causa di [except.spec] N4140/2:

Un specifica delle eccezioni non deve apparire in una dichiarazione typedef o alias-dichiarazione.

Quindi assumerò che la domanda sia per C++ 1z, dove le specifiche delle eccezioni fanno parte del sistema di tipi.


[conv.fctptr]/1:

Un prvalue di tipo “puntatore a noexcept funzione” può essere convertito in un prvalue di tipo “puntatore a funzione”. Il risultato è un puntatore a la funzione.

Pertanto, void (*)() noexcept può essere convertito (implicitamente) in void (*)().

[expr.static.cast]/7:

L'inverso della sequenza di conversione standard (Clausola [conv]) non contenente una conversione [(vari altri casi omessi)] puntatore alla funzione ([conv.fctptr]), può essere eseguito utilizzando esplicitamente static_cast.

Nient'altro [expr.static.cast] permette di convertire void (*)() a void (*)() noexcept sia, quindi questo non è una conversione che può essere eseguita da un static_cast.

[expr.reinterpret.cast]/6:

Un puntatore funzione può essere esplicitamente convertito in un puntatore a funzione di tipo diverso. L'effetto della chiamata di una funzione tramite un puntatore a un tipo di funzione ([dcl.fct]) che non è uguale al tipo utilizzato nella definizione della funzione non è definito. Tranne che conversione di un prvalue di tipo “puntatore a T1” al tipo “puntatore a T2” (dove T1 e T2 sono tipi di funzione) e ritorno al suo tipo originale produce il valore del puntatore originale, il risultato di tale puntatore La conversione non è specificata.[Nota: vedere anche [conv.ptr] per ulteriori dettagli di conversioni puntatore. - end note]

Quindi reinterpret_cast può eseguire questa conversione.

Dal fp2_type(fp) è equivalente al C-style gettato (fp2_type) fp ([expr.type.conv]/1), e since C-style casts do a reinterpret_cast when static_cast is not possible (ignorando const_cast per semplicità, in quanto non è rilevante qui), fp2_type(fp) è un ben formato reinterpret_cast. Il risultato di un cast del genere non può essere utilizzato se non per restituirlo, comunque.

+0

Domanda correlata, se è possibile convertire una funzione no-outs in una normale, puoi fare lo stesso (o viceversa) con i puntatori funzione const e volatile? – dascandy

+0

Esiste una soluzione alternativa per il problema di trasmissione in C++ 11/14. Dichiara una funzione con l'identificatore noexcept, come void f() noexcept; quindi cast come decltype (& f) (fp). Forse aggiungilo alla tua risposta? – user1095108

Problemi correlati