MSDNへの登録が必要のようだが[http://support.microsoft.com/kb/930198](http://support.microsoft.com/kb/930198 "http://support.microsoft.com/kb/930198") にてHotfixが入手できる模様.

Trolltech からパッチっぽいのがでた.[When building Qt 4.2 with MSVC 2005 and Service Pack 1 beta I get compile errors, how can I fix these?](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 のために [Qt4 with Visual Studio - qtnode](http://qtnode.net/wiki/Qt4_with_Visual_Studio "Qt4 with Visual Studio - qtnode") にリンクしておく

VisualStudio2005 の SP1 が出たので,さっくり導入.

400MiB を超えてるせいか,1時間くらいかかってやっとインストール完了.

使った範囲内で問題は出てない—というより,改善点がよくわからない—のだけど,ひとつだけ大問題が発生.

Qt4 のコンパイルに失敗してしまうのだ.


そもそも,MSVCはQt4の Windows/GPL 版の対象外なので,使えなくてもしょうがないっちゃしょうがないんだけども.Q../Freeのパッチを当てると,VisualStudio2005 + PlatformSDK でもコンパイルが可能.

ところが,VS2005にSP1を当てると,”QMultiMap”と”QMultiHash”がコンパイル出来無くなった.

調べてみると,QT-interest のメーリングリストにQt-interest Archive - VS2005 SP1 Final Breaks Qtってなスレッドを発見.そこからさらにMSDN のforumのVisual Studio 2005 Service Pack 1 Beta - error C2244に行き着いた.

どうやら,Qt に限らず,VC8 のテンプレート処理が何かまずいらしい.つまり,template class A の中で “typedef”した型を, BというAを継承したテンプレートクラスの中の関数が返そうとするとコンパイルできないので.コンパイルするには class B の中で改めて “typedef” してそっちを使うようにとVisual Studio 2005 Service Pack 1 release notesRecent versions of the Qt library source give errors on compilation:に書いてある.

コードのほうがわかりやすいので丸々引用すると.

    template 

とすると/* 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 <class Key, class T> 
907: Q_INLINE_TEMPLATE Q_TYPENAME QMap<Key, T>::iterator 
      QMultiMap<Key, T>::replace(const Key &amp;akey, const T &amp;avalue)
908: { return QMap<Key, T>::insert(akey, avalue); }
909: 
910: template <class Key, class T>
911: Q_INLINE_TEMPLATE Q_TYPENAME QMap<Key, T>::iterator 
      QMultiMap<Key, T>::insert(const Key &amp;akey, const T &amp;avalue)
912: { return QMap<Key, T>::insertMulti(akey, avalue); }

QMultiHash は,”QTDIR\src\corelib\tools\qmap.h”の

864: template <class Key, class T> 
865: Q_INLINE_TEMPLATE Q_TYPENAME QHash<Key, T>::iterator 
     QMultiHash<Key, T>::replace(const Key &amp;akey, const T &amp;avalue)
866: { return QHash<Key, T>::insert(akey, avalue); }
867: 
868: template <class Key, class T>
869: Q_INLINE_TEMPLATE Q_TYPENAME QHash<Key, T>::iterator 
      QMultiHash<Key, T>::insert(const Key &amp;akey, const T &amp;avalue)
870: { return QHash<Key, T>::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” も同様にしてみたのをqt4-multi-map-hash-msvc8-sp1.diff においておくのですが,patch の使い方が良くわからないので,使いたい人は,diffファイルの中身を見て適当に解釈してどうぞ.