CString strTest =あいうえお;という変数があって,
void Cxxx::Func(LPCTSTR value);というメソッドに渡す場合は,
Cxxx::Func( (LPCTSTR)strTest );
引数の場合だけでなく代入の場合でも同様な感じです
LPCTSTR value =(LPCTSTR)strTest;
と明示的にoperatorを
今でも呼び出すべきなのでしょうか?
それともこの場合は暗黙にキャストされるようになって,
(LPCTSTR)へのキャストは不要なのでしょうか?
どちらでも通ってしまうのでノーマークだったんですけど...
よろしくお願いします
VS9 XP/Vista/7
明示的にしようと、省略しようと
CSimpleStringT::operator PCXSTR()
キャストオペレータが働くのですが、実はこの子はデータポインタ
を戻す以外何もしないので。
結局「何もしない」という事において、どう書いても同じという認識です。
> それともこの場合は暗黙にキャストされるようになって,
> (LPCTSTR)へのキャストは不要なのでしょうか?
言語仕様書上、キャストっていうのは「変換をソース上に明示すること」なので、
「暗黙にキャスト」ってのは用語が変。
「暗黙の変換」が行われる、のであれば厳密な表現になる。
> 今でも呼び出すべきなのでしょうか?
いらない。俺なら明示しない。
以下は難しい話なので興味があるなら読んでくれ。
誤解してはならないのは
(type) キャストは operator type() の呼び出しではない
ということだ。
提示サンプルを厳密に読み解こうとすると、言語仕様上、2点の理解が必要で、
・関数の多重定義がある場合の、最適候補の選定
・候補選定後の、(暗黙の)型変換
意味が無い変態的な例
struct hoge_t { ... // 何かメンバ変数類が存在して
operator double() const { ... } // double への変換関数がある
};
としよう。この hoge_t は operator float() を持っていない。が
hoge_t h; // コンストラクタが初期化している
int x=(float)h; // 反則すれすれだが合法
はまったく問題なくコンパイルできる。実動作は
h.operator double() const の呼び出し→ double->float 変換→ float->int 変換
で、この例で何をどう書けばよかったのか、は、元のコードの作者の意図次第。
# 単なる思い付きの例なので正解は無いわけだが
提示例で型変換を明示したいのであれば
func(strTest.operator LPCTSTR()); // とすべきであろう。
http://msdn.microsoft.com/ja-jp/library/ms908328.aspx
この辺を読んで混乱してます
ここでは明示的なキャストをしなさい(you must cast it explicitly as LPCTSTR.)と
あって
でも,皆さんは
> どう書いても同じという認識です。
や
> いらない。俺なら明示しない。
と教えてくれます
ひょっとして,
http://msdn.microsoft.com/ja-jp/library/ms908328.aspx
で言っているのは,実は_tprintfに限っての話なんでしょうか???
P.S.
追加です
http://msdn.microsoft.com/ja-jp/library/ms908328.aspx
では
型変換ではなくキャストと書いてあるんですけど,
英語では同じものなんでしょうか?
読み違えてました
追加部分は無かった事で。。。
> 実は_tprintfに限っての話なんでしょうか???
Yes (厳密に言えば、可変個数引数を使うところ)
> ・関数の多重定義がある場合の、最適候補の選定
が可能なのは、あらかじめ関数宣言で引数の型が明示されている場合に限られる。
printf や CString::Format などの可変個数引数部分 ... 領域では、
言語仕様上 C 互換の [既定の型昇格] のみが行われることになっている。
この可変個数引数部分に「非 POD 型」を渡すことは禁じられている (5.2.2-7)
なので可変個数引数部に CString というクラス型 (非 POD) を渡すことはできない。
CString を operator TCHAR* でポインタ型に変換したら渡せるようになるので、
キャストを明示せよと書かれているわけだ。
繰り返すがキャストは必ずしも operator TYPE() の直接呼出しではないので、
提示 MSDN ページのサンプルは、より厳密には
CString str = Some Data;
str.Format(_T(%s%d), str.operator const TCHAR(), 123));
であるべき。
なるほど,すごく理解できました
可変個数引数部分には何が入ってくるのかと考えると,
OldData型で閉じているほうが楽ですものねぇ
でも,CString::FormatってCStringのメソッドなんですから,
「const CString&」型の引数くらい判断して受け付けてくれてもいいのにねぇ
基本的にはLPCTSTRに代入?する場合は「(LPCTSTR)」はつけないでよい
でも,POD待ちな引数には「(LPCTSTR)」はつけてねということですね
ありがとうございました