3

我有一个为 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*,但这我也不想实现。

4

4 回答 4

9

C++ 标准说像这样的隐式转换不适用于省略号参数 - 编译器如何知道要应用什么转换?您必须自己显式执行转换,或者最好停止使用 printf。

于 2010-03-21T10:35:35.903 回答
2

避免转换运算符。他们很少做你想做的事,然后明确的调用是痛苦的。重命名operator const TCHAR*() constTCHAR *str() const.

于 2010-03-21T18:56:24.017 回答
1

当编译器想要将一个值转换为另一种类型时,会调用转换运算符。这适用于采用特定类型的已定义参数的函数。它不适用于像函数声明中的printf()可变参数函数。...这些函数接受参数然后使用它们,因此从不调用转换运算符。

具体来说,当编译器看到 时,无论它是什么printf("%s", foo),它都会传递给,这将不得不假设它适合原样的格式。不会调用转换运算符(尽管会发生某些算术提升)。fooprintf()%s

转换运算符通常会导致问题。通过在该类中使用该运算符,您可以复杂的函数重载解析,因为编译器可以将 a 解释CMyClass为好像它是 a TCHAR *。这可能会导致意外的结果,或者导致代码在您真的不希望编译时编译,或者选择错误的重载函数。(例如,给定CMyClass cmc;,表达式cmc + 10突然合法,因为TCHAR * + int是完全合法的指针算术。)通常的做法是标记这样的转换explicit

于 2010-03-22T19:29:55.293 回答
0

如果您想使用 printf 风格的 API 并依赖转换运算符,那么强制转换是正确的做法(我不会在这里争论您是否应该使用这些功能)。但是,我会使用静态转换,例如_tprintf(_T("%s\n"), static_cast<const TCHAR*>(myClass));

于 2012-08-14T07:55:00.763 回答