2011-12-21 20 views
6

Sto scrivendo un codice 'portatile' (nel senso che esso si rivolge a 32 e 64 bit MSVC2k10 e GCC su Linux), in cui ho, più o meno:Sovraccarico globale dell'operatore typecast?

typedef unsigned char uint8; 

C-stringhe sono sempre uint8 ; questo è per motivi di elaborazione delle stringhe. Il codice legacy richiede che il char sia compilato come firmato, quindi non posso impostare gli switch del compilatore come predefiniti su unsigned. Ma se sto elaborazione di una stringa non posso benissimo indice di un array:

char foo[500]; 
char *ptr = (foo + 4); 
*ptr = some_array_that_normalizes_it[*ptr]; 

Non è possibile indicizzare una matrice con un numero negativo in fase di esecuzione, senza gravi conseguenze. Mantenere C-string senza segno consente una protezione più semplice dai bug.

Vorrei davvero non dover continuare a eseguire il cast (char *) ogni volta che utilizzo una funzione che richiede char * e smettere di duplicare le funzioni di classe in modo da poterle utilizzare. Questo è particolarmente un dolore perché una stringa costante è implicitamente passato come char *

int foo = strlen("Hello"); // "Hello" is passed as a char * 

Voglio che tutti questi per lavorare:

char foo[500] = "Hello!"; // Works 
uint8 foo2[500] = "Hello!"; // Works 
uint32 len = strlen(foo); // Works 
uint32 len2 = strlen(foo2); // Doesn't work 
uint32 len3 = strlen((char *)foo2); // Works 

Probabilmente ci sono avvertimenti a consentire conversioni di tipo implicito di questa natura , comunque, sarebbe bello usare le funzioni che prendono un char * senza un cast ogni volta.

Così, ho pensato che qualcosa di simile potrebbe funzionare:

operator char* (const uint8* foo) { return (char *)foo; } 

Tuttavia non è così. Non riesco a trovare un modo per farlo funzionare. Anche io non riesco a trovare nulla per dirmi perché non sembra esserci alcun modo per farlo. Riesco a vedere la logica possibile - conversioni implicite come quella potrebbero essere una causa di FAR troppi bug - ma non riesco a trovare nulla che dice "questo non funzionerà in C++" o perché, o come farlo funzionare (a corto di rendere uin8 una classe che è ridicola).

+3

Non è possibile scrivere cast (o operatori) che non coinvolgano almeno un tipo definito dall'utente –

+0

Si dispone di codice legacy che utilizza 'char firmato '?? Dubito molto che ... –

+2

perché sta rendendo uint8 una classe ridicola? Non è più ridicolo che avere un sacco di funzioni di casting globali vaganti. – ThomasMcLeod

risposta

1

Non sono un grande fan dell'operatore [ab] che utilizza, ma questo è quello che C++ è giusto?

È possibile effettuare le seguenti operazioni:

const char* operator+(const uint8* foo) 
{ 
    return (const char *)foo; 
} 

char* operator+(uint8* foo) 
{ 
    return (char *)foo; 
} 

con quelli definiti, il vostro esempio dall'alto:

uint32 len2 = strlen(foo2); 

diventerà

uint32 len2 = strlen(+foo2); 

Non è un cast automatico, ma in questo modo hai un modo semplice ma esplicito di farlo.

+0

Grazie, buona idea! –

+0

Wow ............ –

0

Entrambi i compilatori a cui si fa riferimento hanno uno switch "Trattamento caratteri come non firmato". Perché non usarlo?

+0

Rompere il codice legacy. Come ho detto in ... la seconda frase. –

+0

Oh ... allora non sono sicuro della natura del tuo programma. Pensavo che stavi scrivendo qualcosa di nuovo! (come hai detto tu nella prima frase) –

3

fusione globale (typecast) operatore, operatore di assegnazione globale, operatore indice di matrice globale e globale chiamata di funzione overload degli operatori sono non ammessi in C++.

MSVS C++ sarà genererà C2801 errors su di loro. Look at wiki per un elenco di operatori C++ e regole di sovraccarico.