2010-03-21 79 views
3

我有一个定义的TCHAR *用户定义的运算符我希望能够像做用户定义的转换操作符作为论据的printf

CMyClass myClass; 
_tprintf(_T("%s"), myClass); 
一类,像这样

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

甚至

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

但尝试时,printf始终打印(空)而不是值。我也尝试了正常的char *运营商,以及与常量等的变化 它只是正常工作,如果我显式调用操作或做一个演员,就像

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

不过,我不想投。这怎么能实现?

请注意,有可能创建一个函数,该函数的参数为​​const TCHAR *,以便它强制调用运算符TCHAR *,但是这也是我不想实现的。

回答

2

避免转换操作员。他们很少做你想要的,然后明确的呼叫是痛苦的。将operator const TCHAR*() const重命名为TCHAR *str() const

+0

或为什么不实现const TCHAR * operator()()const {}; – Rahul 2017-02-22 18:06:05

9

C++标准规定像这样的隐式转换不适用于省略号参数 - 编译器如何知道要应用哪种转换?您必须自己明确地执行转换,或者更好地停止使用printf。

+4

+1停止使用printf – 2010-03-21 10:38:59

+3

我宁愿停止使用转换运算符。 – UncleBens 2010-03-21 13:18:29

+0

@UncleBens为了编写可读的代码,一些转换是非常必要的。例如,我们将不需要将char *转换为字符串。 – 2010-03-21 13:24:07

1

当编译器想要将值转换为另一种类型时调用转换运算符。这适用于采用特定类型的已定义参数的函数。它在函数声明中不适用于printf()...等可变函数。这些函数接受参数,然后与它们一起工作,所以转换操作符永远不会被调用。

具体而言,当编译器看到printf("%s", foo),它通过foo,不管是什么,对printf(),这将不得不假设它是适合,因为它是一个%s格式。将不会调用转换操作员(尽管会进行某些算术升级)。

转换运营商通常会导致问题。通过在该类中使用该运算符,您的函数重载分辨率会变得非常复杂,因为编译器可以将CMyClass解释为TCHAR *。这可能会导致意外的结果,或者导致代码在您不需要时进行编译,或者选择错误的重载函数。 (例如,给出CMyClass cmc;,表达式cmc + 10突然合法,因为TCHAR * + int是完全合法的指针算术。)通常的做法是标记这样的转换explicit

0

如果您想使用printf样式的API并依赖转换操作符(并且我不打算在这里争论您是否应该使用这些功能),则此操作是正确的。不过,我会使用静态投射,例如_tprintf(_T("%s\n"), static_cast<const TCHAR*>(myClass));