2010-03-21 51 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));