I'm writing some 'portable' code (meaning that it targets 32- and 64-bit MSVC2k10 and GCC on Linux) in which I have, more or less:
typedef unsigned char uint8;
C-strings are always uint8; this is for string-processing reasons. Legacy code needs char compiled as signed, so I can't set compiler switches to default it to unsigned. But if I'm processing a string I can't very well index an array:
char foo[500];
char *ptr = (foo + 4);
*ptr = some_array_that_normalizes_it[*ptr];
You can't index an array with a negative number at run-time without serious consequences. Keeping C-strings unsigned allows for such easier protection from bugs.
I would really like to not have to keep casting (char *) every time I use a function that takes char *'s, and also stop duplicating class functions so that they take either. This is especially a pain because a string constant is implicitly passed as a char *
int foo = strlen("Hello"); // "Hello" is passed as a char *
I want all of these to work:
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
There are probably caveats to allowing implicit type conversions of this nature, however, it'd be nice to use functions that take a char * without a cast every time.
So, I figured something like this would work:
operator char* (const uint8* foo) { return (char *)foo; }
However it does not. I can't figure out any way to make it work. I also can't find anything to tell me why there seems to be no way to do this. I can see the possible logic - implicit conversions like that could be a cause of FAR too many bugs - but I can't find anything that says "this will not work in C++" or why, or how to make it work (short of making uin8 a class which is ridiculous).
In C++, we can make operators work for user-defined classes. This means C++ has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading.
No we cannot overload integer or float types because overloading means to change the working of existing operators or make them to work with objects int is single member not an object.
Operator Overloading is the method by which we can change the function of some specific operators to do some different task. In the above syntax Return_Type is value type to be returned to another object, operator op is the function where the operator is a keyword and op is the operator to be overloaded.
To overload the function that casts our class to an int, we write a new function in our class called operator int(). Note that there is a space between the word operator and the type we are casting to. User-defined conversions do not take parameters, as there is no way to pass arguments to them.
Global cast(typecast) operator, global assignment operator, global array subscript operator and global function call operator overloading are not allowed in C++.
MSVS C++ will be generate C2801 errors on them. Look at wiki for list of C++ operators and them overloading rules.
I'm not a big fan of operator [ab]using, but thats what c++ is for right?
You can do the following:
const char* operator+(const uint8* foo)
{
return (const char *)foo;
}
char* operator+(uint8* foo)
{
return (char *)foo;
}
With those defined, your example from above:
uint32 len2 = strlen(foo2);
will become
uint32 len2 = strlen(+foo2);
It is not an automatic cast, but this way you have an easy, yet explicit way of doing it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With