LPCTSTRへのキャスト – プログラミング – Home

通知
すべてクリア

[解決済] LPCTSTRへのキャスト


hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
Topic starter  

CString strTest  =あいうえお;という変数があって,
void Cxxx::Func(LPCTSTR value);というメソッドに渡す場合は,

Cxxx::Func( (LPCTSTR)strTest );
引数の場合だけでなく代入の場合でも同様な感じです
LPCTSTR value  =(LPCTSTR)strTest;

と明示的にoperatorを
今でも呼び出すべきなのでしょうか?

それともこの場合は暗黙にキャストされるようになって,
(LPCTSTR)へのキャストは不要なのでしょうか?

どちらでも通ってしまうのでノーマークだったんですけど...
よろしくお願いします

VS9 XP/Vista/7


引用未解決
トピックタグ
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

明示的にしようと、省略しようと
CSimpleStringT::operator PCXSTR()
キャストオペレータが働くのですが、実はこの子はデータポインタ
を戻す以外何もしないので。
結局「何もしない」という事において、どう書いても同じという認識です。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

> それともこの場合は暗黙にキャストされるようになって,
> (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()); // とすべきであろう。


返信引用
hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
Topic starter  

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に限っての話なんでしょうか???


返信引用
hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
Topic starter  

P.S.
追加です
http://msdn.microsoft.com/ja-jp/library/ms908328.aspx
では
型変換ではなくキャストと書いてあるんですけど,
英語では同じものなんでしょうか?


返信引用
hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
Topic starter  

読み違えてました
追加部分は無かった事で。。。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

> 実は_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));
であるべき。


返信引用
hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
Topic starter  

なるほど,すごく理解できました
可変個数引数部分には何が入ってくるのかと考えると,
OldData型で閉じているほうが楽ですものねぇ
でも,CString::FormatってCStringのメソッドなんですから,
「const CString&」型の引数くらい判断して受け付けてくれてもいいのにねぇ

基本的にはLPCTSTRに代入?する場合は「(LPCTSTR)」はつけないでよい
でも,POD待ちな引数には「(LPCTSTR)」はつけてねということですね

ありがとうございました


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました