我有一个为TCHAR *定义用户定义的运算符的类,如此
CMyClass::operator const TCHAR*() const
{
// returns text as const TCHAR*
}
我希望能够做一些像
这样的事情CMyClass myClass;
_tprintf(_T("%s"), myClass);
甚至
_tprintf(_T("%s"), CMyClass(value));
但是在尝试时,printf总是打印(null)而不是值。我也尝试了一个普通的char *运算符,以及const等变量。 它只有在我明确调用运算符或进行强制转换时才能正常工作,比如
_tprintf(_T("%s\n"), (const TCHAR*)myClass);
_tprintf(_T("%s\n"), myClass.operator const TCHAR *());
但是,我不想演员。如何实现这一目标?
注意,有可能创建一个参数为const TCHAR *的函数,以便强制调用运算符TCHAR *,但这也是我不想实现的。
答案 0 :(得分:9)
C ++标准说这样的隐式转换不适用于省略号参数 - 编译器如何知道要应用的转换?您必须自己明确地执行转换,或者更好地停止使用printf。
答案 1 :(得分:2)
避免转换运算符。他们很少做你想做的事情,然后明确的电话是痛苦的。将operator const TCHAR*() const
重命名为TCHAR *str() const
。
答案 2 :(得分:1)
当编译器想要将值转换为另一种类型时,将调用转换运算符。这适用于采用特定类型的已定义参数的函数。它对于函数声明中的printf()
和...
等可变函数不起作用。这些函数接受参数然后使用它们,因此永远不会调用转换运算符。
具体来说,当编译器看到printf("%s", foo)
时,它会将foo
传递给printf()
,%s
必须假设它适合CMyClass
格式原样。不会调用转换运算符(虽然会进行某些算术促销)。
转换运算符通常会导致问题。通过在该类中使用该运算符,您将复杂的函数重载解析,因为编译器可以将TCHAR *
解释为CMyClass cmc;
。这可能会导致意外的结果,导致代码在您真正不想要时编译,或者选择错误的重载函数。 (例如,给定cmc + 10
,表达式TCHAR * + int
突然合法,因为explicit
是完全合法的指针算法。)通常的做法是标记此类转换{{1}}。< / p>
答案 3 :(得分:0)
如果您想使用printf样式API并依赖转换运算符,那么转换是正确的(我不打算在这里争论您是否应该使用这些功能)。但是,我会使用静态演员,例如_tprintf(_T("%s\n"), static_cast<const TCHAR*>(myClass));