2011-12-21 26 views
6

estoy escribiendo algo de código 'portátil' (lo que significa que se dirige de 32 y 64 bits MSVC2k10 y GCC en Linux) en la que tengo, más o menos:¿Sobrecarga del operador de tipografía global?

typedef unsigned char uint8; 

C-secuencias son siempre uint8 ; esto es por razones de procesamiento de cadenas. El código heredado necesita un compilador como firmado, por lo que no puedo configurar los modificadores del compilador para que no estén firmados. Pero si yo estoy procesando una cadena no puedo muy bien índice de una matriz:

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

No se puede indizar una matriz con un número negativo en tiempo de ejecución sin consecuencias graves. Mantener C-strings sin firmar permite una protección más fácil contra los errores.

Realmente me gustaría no tener que seguir emitiendo (char *) cada vez que utilizo una función que toma char * 's, y también dejo de duplicar funciones de clase para que tomen cualquiera. Esto es especialmente un dolor debido a una constante de cadena se pasa implícitamente como un char *

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

Quiero que todos estos para trabajar:

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 

Probablemente hay advertencias de permitir conversiones de tipo implícitas de esta naturaleza Sin embargo, sería bueno usar funciones que tengan un carácter * sin un molde cada vez.

Por lo tanto, pensé que algo como esto funcionaría:

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

Sin embargo no es así. No puedo encontrar la manera de hacerlo funcionar. Tampoco puedo encontrar nada que me diga por qué parece que no hay forma de hacerlo. Puedo ver la posible lógica - las conversiones implícitas como esa podrían ser una causa de demasiados errores de FAR - pero no puedo encontrar nada que diga "esto no funcionará en C++" o por qué, o cómo hacerlo funcionar (menos de haciendo uin8 una clase que es ridícula).

+3

No puede escribir moldes (u operadores) que no impliquen al menos un tipo definido por el usuario –

+0

Tiene un código heredado que usa 'signed char' ?? Dudo mucho que ... –

+2

¿por qué está haciendo uint8 una clase ridícula? No es más ridículo que tener un montón de funciones de casting global. – ThomasMcLeod

Respuesta

1

No soy un gran admirador del operador [ab], pero eso es lo que C++ es para ¿verdad?

Usted puede hacer lo siguiente:

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

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

Con los que se definen, a su ejemplo de arriba:

uint32 len2 = strlen(foo2); 

se convertirá en

uint32 len2 = strlen(+foo2); 

No es un reparto automático, pero de esta manera tienes una forma fácil pero explícita de hacerlo.

+0

¡Gracias, buena idea! –

+0

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

0

Ambos compiladores que usted menciona tienen un interruptor "tratar caracteres como no firmados". ¿Por qué no usar eso?

+0

Rompiendo código heredado. Como dije en ... como la segunda oración. –

+0

Oh ... No estoy seguro de la naturaleza de tu programa en ese momento. ¡Pensé que estabas escribiendo algo nuevo! (como dijiste en la primera oración) –

3

operador, operador de asignación global, operador global subíndice de matriz y la sobrecarga global de operador de llamada de función fundido Global (encasillado) están no permitido en C++.

MSVS C++ generará C2801 errors en ellos. Look at wiki para la lista de operadores C++ y las reglas de sobrecarga.