views:

205

answers:

4

I have a class that defined a user defined operator for a TCHAR*, like so

CMyClass::operator const TCHAR*() const
{
    // returns text as const TCHAR*
}

I want to be able to do something like

CMyClass myClass;
_tprintf(_T("%s"), myClass);

or even

_tprintf(_T("%s"), CMyClass(value));

But when trying, printf always prints (null) instead of the value. I have also tried a normal char* operator, as well variations with const etc. It only works correctly if I explicitly call the operator or do a cast, like

_tprintf(_T("%s\n"), (const TCHAR*)myClass);
_tprintf(_T("%s\n"), myClass.operator const TCHAR *());

However, I don't want to cast. How can this be achieved?

Note, that a possibility is to create a function that has a parameter of const TCHAR*, so that it forcible calls the operator TCHAR*, but this I also don't want to implement.

+8  A: 

The C++ Standard says that implicit conversions like this are not applied to ellipsis parameters - how would the compiler know what conversion to apply? You will have to perform the conversion explicitly yourself, or better yet stop using printf.

anon
+1 for stop using printf
Space_C0wb0y
I would rather stop using conversion operators.
UncleBens
@UncleBens Some conversions are really necessary in order to write readable code. where would we be without the conversion from char * to string, for example.
anon
In his case, the direction rather looks like string to char const*, and in that case a member function is used. I recommend a `myClass.c_text()` or something along that.
Johannes Schaub - litb
+1  A: 

Avoid conversion operators. They rarely do what you want, and then explicit calls are painful. Rename operator const TCHAR*() const to TCHAR *str() const.

Potatoswatter
A: 

Don't know how to accept an answer, but I've seen it working, although I haven't got the code for it and I just can't remember the details.

Anyhow, I will (at least for now) stick to a method that returns a TCHAR* (as proposed by Johannes Schaub and Potateswatter)

BC
You should see a hollow check mark next to answers. Click on the hollow check mark next to the answer you want to accept. It's worth doing.
David Thornley
A: 

Conversion operators are called when the compiler wants to convert a value to another type. This works for functions that take defined parameters of specific types. It doesn't work for variadic functions like printf() with ... in the function declaration. These functions take the arguments and then work with them, so the conversion operator is never called.

To be specific, when the compiler sees printf("%s", foo), it passes foo, whatever it is, to printf(), which will have to assume it's suitable for a %s format as it is. No conversion operator will be called (although certain arithmetic promotions will take place).

Conversion operators in general cause problems. By having that operator in that class, you've complicated function overload resolution, since the compiler can interpret a CMyClass as if it were a TCHAR *. This can cause unexpected results, either causing code to compile when you really didn't want it to, or selecting the wrong overloaded function. (For example, given CMyClass cmc;, the expression cmc + 10 is suddenly legal, since TCHAR * + int is perfectly legitimate pointer arithmetic.) The usual practice is to label such conversions explicit.

David Thornley