おせわになります。はてなくんです。
CMapをはじめて使ってみようと思いましたが
エラーが出てしまいます。
文字列、文字列のマップと文字列、intのマップを使いたいです。
ChogeAppのヘッダファイルの先頭あたりに
CMap<CString CString&, int, int&> mapInt; // 文字列 - int
mapInt m_mapInt; // 文字列 - int のメンバ
CMapStringToString m_mapStr; // 文字列 - 文字列のメンバ
下記のエラーが出て、怒られてしまいました。(T_T;
hoge.h(17) : error C2146: 構文エラー : ',' が、識別子 'CString' の前に必要です。
メンバ変数にもつにはどうしたらよいでしょうか?
ご指導お願いします。
by @@?はてなくん
> mapInt m_mapInt; // 文字列 - int のメンバ
mapIntは変数名ですが……。
> hoge.h(17) : error C2146: 構文エラー : ',' が、識別子 'CString' の前に必要です。
hoge.hの17行目というのはどこですか?
YuO殿 お返事ありがとうございます。
>mapIntは変数名ですが……。
おはずかしい。。。
class CHogeApp : public CWinApp
{
public:
CMap<CString CString&, int, int&> m_mapInt; // 29行目
CMapStringToString m_mapStr;
としましたが
hoge.h(29) : error C2146: 構文エラー : ',' が、識別子 'CString' の前に必要です
となってしまいました。
なにがおかしいのでしょうか?
よろしくお願いします。
by @@?はてなくん
コンパイラのおっしゃるとおりです。
CMap<CString CString&, int, int&> m_mapInt; // 29行目
^<-- ここにカンマがないじゃん。
επιστημη殿 お返事ありがとうございます。
> ^<-- ここにカンマがないじゃん。
おはずかしい、Part2
修正後は次なるエラーが出ました。
error C2440: 'type cast' : 'class CString' から 'unsigned long' に変換することは
できません。
この変換を実行可能なユーザー定義変換演算子がないか、または演算子を呼び出せません。
afxtempl.h(1324) : コンパイルされたクラスのテンプレートのインスタンス化 'unsigned int __stdcall
HashKey(class CString &)' の参照を確認してください
さっぱりわからないです。(T_T;
ご指導お願いします。
by @@?はてなくん
> error C2440: 'type cast' : 'class CString' から 'unsigned long' に
> 変換することはできません。
だからぁ、そのエラーがどこで出たんです? コードを示さないとわかりませんてば。
>だからぁ、そのエラーがどこで出たんです?
MFCのソース
afxtempl.h(129)のようです。
>template<class ARG_KEY>
>AFX_INLINE UINT AFXAPI HashKey(ARG_KEY key)
>{
> // default identity hash - works for most primitive values
> return ((UINT)(void*)(DWORD)key) >> 4; // ここが129行のようです
>}
ARG_KEYとなっているので CString& がいけないのでしょうか?
MSDNのARG_KEYの説明には
KEY 引数として使うデータ型。通常、KEY への参照です。
とかかれているのですけれど @@???
よろしくお願いします。
なるほど...
CMap<CString, LPCTSTR, int, int> m_mapInt;
に置き換えてみてくださいな。
επιστημη殿 即答ありがとうございます。
>CMap<CString, LPCTSTR, int, int> m_mapInt;
>に置き換えてみてくださいな。
上記のとおりにかえたら、うまくいきました。
LPCTSTRを調べたら const char * と等価のようです。
なぜ CString& がダメで const char * がOKなのか
理由を教えていただけないでしょうか?
お願いいたします。m(__)m
by @@?はてなくん
>template<class ARG_KEY>
>AFX_INLINE UINT AFXAPI HashKey(ARG_KEY key)
>{
> // default identity hash - works for most primitive values
> return ((UINT)(void*)(DWORD)key) >> 4; // ここが129行のようです
>}
ここで,最初のソースではARG_KEYがCString&ですから,
template<> AFX_INLINE UINT AFXAPI HashKey(CString& key)
{
return ((UINT)(void*)(DWORD)key) >> 4;
}
という風な暗黙の特殊化が行われます。
ここで,(DWORD)key,つまりCString&型の変数keyをDWORDにキャ
ストしようとしていますが,
CStringをDWORDにキャストすることはできないので,コンパイルエラーがでています。
template<> AFX_INLINE UINT AFXAPI HashKey(LPCTSTR key)
{
return ((UINT)(void*)(DWORD)key) >> 4;
}
であれば,keyはconst char(/wchar_t) *型の変数ですから,
DWORD型にreinterpret_castすることができます。
そのため,コンパイルができるようになっています。
ちなみに,
template<> AFX_INLINE UINT AFXAPI HashKey(CString& key)
{
return HashKey(static_cast<LPCTSTR>(key));
}
なんていう明示的な特殊化を追加すれば,
CMap<CString, CString&, int, int>でもコンパイル可能です。
YuO殿
詳しい解説をありがとうございました。
ただMSDNには通常KEYへの参照です。とかかれているのに
そう宣言できないのが、イマイチ納得できません。
MFCのソースを見ないとわからないということですよね?
ただ、実際には CString::operator = が働くので
CString& を渡せばいけるのでしょうけど。。。
補足
template<> AFX_INLINE UINT AFXAPI HashKey(LPCTSTR key)
{
return ((UINT)(void*)(DWORD)key) >> 4;
}
これではまともなHashKeyは作成できません。
実際にはLPCTSTRの場合には専用のHashKey関数が用意されているのでそちらが使用されます。
さらに補足
> ただMSDNには通常KEYへの参照です。とかかれているのに
これ、ウソっぽい。ただしくは 'KEYへのconst参照'ではないかしら。
>これ、ウソっぽい。ただしくは 'KEYへのconst参照'ではないかしら。
悪いのは HogeKuroSoft だとわかりました。
皆様ありがとうございました。
>>これ、ウソっぽい。ただしくは 'KEYへのconst参照'ではないかしら。
> 悪いのは HogeKuroSoft だとわかりました。
...わかってないと思う^^;