====== Qt4.2.2 を VS2005+SP1(vc8) で使う ====== meta-creation_date: 2006-12-17T05:30:45+09:00 meta-entiry_id: qt4_msvc8_sp1_problem meta-author: t.ashula meta-tags: Programming,Qt4,MSVC,C++,SP1 MSDNへの登録が必要のようだが[[http://support.microsoft.com/kb/930198|http://support.microsoft.com/kb/930198]] にてHotfixが入手できる模様. Trolltech からパッチっぽいのがでた.[[http://www.trolltech.com/developer/knowledgebase/faq.2006-12-18.3281869860|When building Qt 4.2 with MSVC 2005 and Service Pack 1 beta I get compile errors, how can I fix these?]] いつの間にか,前述のページが無味乾燥としたものになってるので,愚繰ってたどり着いた 主に non Japanese のために [[http://qtnode.net/wiki/Qt4_with_Visual_Studio|Qt4 with Visual Studio - qtnode]] にリンクしておく [[http://www.microsoft.com/downloads/details.aspx?FamilyID=bb4a75ab-e2d4-4c96-b39d-37baf6b5b1dc&DisplayLang=ja|VisualStudio2005 の SP1]] が出たので,さっくり導入. 400MiB を超えてるせいか,1時間くらいかかってやっとインストール完了. 使った範囲内で問題は出てない---というより,改善点がよくわからない---のだけど,ひとつだけ大問題が発生. Qt4 のコンパイルに失敗してしまうのだ. ----- そもそも,MSVCは[[http://www.trolltech.com/products/qt|Qt4]]の Windows/GPL 版の対象外なので,使えなくてもしょうがないっちゃしょうがないんだけども.[[http://sourceforge.net/projects/qtwin/|Q../Free]]のパッチを当てると,VisualStudio2005 + PlatformSDK でもコンパイルが可能. ところが,VS2005にSP1を当てると,''QMultiMap''と''QMultiHash''がコンパイル出来無くなった. 調べてみると,QT-interest のメーリングリストに[[http://lists.trolltech.com/qt-interest/2006-12/thread00584-0.html|Qt-interest Archive - VS2005 SP1 Final Breaks Qt]]ってなスレッドを発見.そこからさらにMSDN のforumの[[http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=987536&SiteID=1|Visual Studio 2005 Service Pack 1 Beta - error C2244]]に行き着いた. どうやら,Qt に限らず,VC8 のテンプレート処理が何かまずいらしい.つまり,template class A の中で ''typedef''した型を, BというAを継承したテンプレートクラスの中の関数が返そうとするとコンパイルできないので.コンパイルするには class B の中で改めて ''typedef'' してそっちを使うようにと[[http://support.microsoft.com/Default.aspx?kbid=928957|Visual Studio 2005 Service Pack 1 release notes]]の""=http://support.microsoft.com/Default.aspx?kbid=928957|Recent versions of the Qt library source give errors on compilation:""に書いてある. コードのほうがわかりやすいので丸々引用すると.
template class A { public: typedef int N_A; }; template ; class B : public A { public: typename A<;T>::N_A test(); }; template typename A::N_A B::test() /* 1 */ { return 0; }
とすると/* 1 */ のところでコンパイルエラーになるので
template class A { public: typedef int N_A; }; template class B : public A { public: typedef A::N_A N_B; // typedef definition typename N_B test(); // use of the typedef in the return type }; template typename B::N_B B::test() // use of the typedef in the return type { return 0; }
という風にしなさいよということのようだ. それならばと,Qtの問題の箇所の QMultiMapとQMultiHash を確認してみる 具体的には QMultiMap は,''QTDIR\src\corelib\tools\qmap.h''で 906: template 907: Q_INLINE_TEMPLATE Q_TYPENAME QMap::iterator QMultiMap::replace(const Key &akey, const T &avalue) 908: { return QMap::insert(akey, avalue); } 909: 910: template 911: Q_INLINE_TEMPLATE Q_TYPENAME QMap::iterator QMultiMap::insert(const Key &akey, const T &avalue) 912: { return QMap::insertMulti(akey, avalue); } QMultiHash は,''QTDIR\src\corelib\tools\qmap.h''の 864: template 865: Q_INLINE_TEMPLATE Q_TYPENAME QHash::iterator QMultiHash::replace(const Key &akey, const T &avalue) 866: { return QHash::insert(akey, avalue); } 867: 868: template 869: Q_INLINE_TEMPLATE Q_TYPENAME QHash::iterator QMultiHash::insert(const Key &akey, const T &avalue) 870: { return QHash::insertMulti(akey, avalue); } のあたり.これを,リリースノートの状況に照らし合わせると ^class A|class QMap/QHash| ^class B|class QMultiMap/QMultiHash| ^N_A|iterator| ^test()|replace()/insert()| となるので,QMultiMap の修正は,''typedef'' で ''QMultiMap::QMapItr'' 型を追加.''inser(),replace()''の返り値を ''QMultiMap::QMapItr'' 型にすると言うことになる. class QMultiMap : public QMap { public: typedef QMap::iterator QMapItr; // rename inline typename QMapItr insert( const Key &key, const T &value ); } template Q_INLINE_TEMPLATE Q_TYPENAME QMultiMap::QMapItr QMultiMap::insert(const Key &akey, const T &avalue) { return QMap::insert(akey, avalue); } それで,''QMultiMap::replace, QMultiHash::insert, QMultiHash::replace'' も同様にしてみたのを[[/files/mt/qt4-multi-map-hash-msvc8-sp1.diff|qt4-multi-map-hash-msvc8-sp1.diff]] においておくのですが,patch の使い方が良くわからないので,使いたい人は,diffファイルの中身を見て適当に解釈してどうぞ.