User defined conversion operator as argument for printf
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.
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.
Avoid conversion operators. They rarely do what you want, and then explicit calls are painful. Rename operator const TCHAR*() const
to TCHAR *str() const
.
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
.
Casting is the right thing to do if you want to use printf style APIs and rely on a conversion operator (and I am not going to argue here whether or not you should use these features). However, I would use static cast, e.g. _tprintf(_T("%s\n"), static_cast<const TCHAR*>(myClass));
精彩评论