I'm making my own string class and I was wondering if there's any way to replace the compiler behaviour around " characters.
As I said in the title I'd like to make it so that CString a = "Hello " + "World!"; would actually work and not give a compiler error telling that it can't add 2 pointers.
My string class automatically converts to char* when needed and thus writing printf(a) would not break the code.
I'm sure this is a rather weird question but if it's possible I'd really like to know how to do it.
Thank you very much
views:
223answers:
2You can't do exactly that because you can only overload operators for class types, and a string literal does not have class type.
You can take advantage of the concatenation of string literals that takes place during preprocessing:
CString a = "Hello " "World!";
or you can create a CString
temporary and append to it:
CString a = CString("Hello ") + "World!";
or you could have a CString
constructor that takes more than one argument:
CString a("Hello ", "World!");
The right answer
No. You cannot overload operators for built-ins, such as pointers.
James McNellis already answered the question, so I won't elaborate.
A possible alternative...
(I use std::string because I have no info on your in-house string)
Using a typedef will add some sugar to your syntax:
typedef std::string S_ ;
int main(int argc, char* argv[])
{
std::string s = S_("Hello") + S_(" World") ;
std::cout << "s : " << s << std::endl ;
return 0 ;
}
But then, I wouldn't pollute the global namespace with a two-characters symbol just for a little sugar... And as far as I know, the code is inefficient (two string objects created, plus one temporary, without guarantee the compiler will optimize it all away...)
For curiosity's sake...
As a curiosity, by wrapping the string into a thin class, you can "add" those two pointers.
First, let's create the wrapper :
class StringThinWrapper
{
public :
StringThinWrapper(const char * p) : m_p(p) {}
operator const char * () const { return m_p ; }
private :
const char * const m_p ;
} ;
As you can see, it's both inlined, and will do nothing... Still, it's able to cast itself into a const char * pointer (this kind of hack is dangerous, so be sure it's what you want to do).
Then, for this wrapper, let's overload the addition operator :
inline std::string operator + (const StringThinWrapper & lhs, const StringThinWrapper & rhs)
{
std::string s(lhs) ;
s += rhs ;
return s ;
}
And now, let's write a main
function using the wrapper, typedefed for ease of use :
typedef StringThinWrapper S_ ;
int main(int argc, char* argv[])
{
std::string s = S_("Hello") + S_(" World") ;
std::cout << "s : " << s << std::endl ;
return 0 ;
}
Which compiles and gives the following result :
s : Hello World
Disclaimer: I just wanted to play with the idea your question gave me, and share it with you. Don't apply this kind of code just because you can. Indeed, this code should be refined to cover all cases efficiently before even being used, and even then, a simple typedef std::string S_ ;
would be better IMHO.
AFAIK, I wouldn't use it because I'm happy with the current STL API.
And what about C++0x ?
In C++0x, you'll be able to create your own literals. The code will be kinda like :
std::string operator "str"(const char * p)
{
return std::string(p);
}
And you'll use it so :
int main(int argc, char * argv[])
{
std::string s = "Hello"str + " World"str ;
std::cout << "s : " << s << std::endl ;
return 0 ;
}
For more information, see the following SO question: http://stackoverflow.com/questions/237804.