2014-09-06 8 views
34

Cosa fa il seguente? Pensavo che + fosse solo per la promozione di interi.Qual è lo scopo dell'operatore unario più sul char array?

char c[20] = "hello"; 
foo(+c); 
foo(+"hello"); 
+7

Il caso più strano di questo è * lambda positivo *, che fa esattamente lo stesso per decadere il lambda in un puntatore di funzione: '+ []() {}' – Manu343726

+1

@ Manu343726 Nella tua espressione, il puntatore di funzione risultante è valido ? O la funzione lambda anonima è già fuori portata? Inserito nel codice, è '(* + []() {})()' valido? – Ponkadoodle

risposta

32

costringe l'array decada a un puntatore, come indicato nella indirettamente §5.3.1 [expr.unary.op]/7:

L'operando dell'operatore unario + avranno aritmetica, enumerazione senza ambito o tipo di puntatore e il risultato è il valore dell'argomento. La promozione integrale viene eseguita su operandi integrali o di enumerazione. Il tipo del risultato è il tipo dell'operando promosso.

All'inizio non è possibile vederlo, ma poiché un array non è uno dei tipi elencati, è necessario convertirlo in un puntatore per adattarlo. Da lì, viene restituito il valore del puntatore.

In entrambi i casi, uno foo(const char *) sarà scelto su un foo(const char(&)[N]). Per alcuni esempi di cose utili puoi usare unario plus per, vedi this answer. Sono inclusi la conversione di un tipo di enum in un numero intero e il superamento di un problema di collegamento. Come dici tu, può anche essere usato per la promozione integrale. Ad esempio, unsigned char byte = getByte(); std::cout << +byte; stamperà il valore numerico e mai il carattere.


Un esempio semplice è:

char a[42]; 
cout << sizeof(a) << endl; // prints 42 
cout << sizeof(+a) << endl; // prints 4 
+0

'stamperà il valore numerico e mai il carattere' ... a meno di' sizeof (char) == sizeof (int) ', giusto? – fredoverflow

+9

@FredOverflow 'char' e' unsigned char' vengono sempre promossi a 'int' o' unsigned int', anche se hanno già la stessa dimensione. – hvd

+0

È un idioma comune in C++, oppure esiste un modo migliore di scriverlo (ad esempio un cast) che rende più evidente ciò che sta succedendo? –

22

unario + non è definito solo per i tipi numerici, ma anche per i tipi di puntatore. Non è definito, tuttavia, per gli array.

Quindi, foo(+c) forze c da convertire in un puntatore al suo primo elemento. Se foo è una funzione definita come prendendo uno char *, ciò non sarebbe necessario: sarebbe già accaduto implicitamente. Può avere importanza quando si hanno sovraccarichi (probabilmente tramite una funzione template), comunque.