====== 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ファイルの中身を見て適当に解釈してどうぞ.