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 にてHotfixが入手できる模様.

Trolltech からパッチっぽいのがでた.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 にリンクしておく

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

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

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

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

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

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

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

どうやら,Qt に限らず,VC8 のテンプレート処理が何かまずいらしい.つまり,temlate 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 <class T>
class A
{
public:
    typedef int N_A;
};

template <class T>
class B : public A<T>
{
public:
    typename A<T>::N_A test();
};

template <class T>
typename A<T>::N_A B<T>::test()    /* 1 */
{ 
    return 0;
}

とすると/* 1 */ のところでコンパイルエラーになるので

template <class T>
class A
{
public:
    typedef int N_A;
};

template <class T>
class B : public A<T>
{
public:
    typedef A<T>::N_A N_B;  // typedef definition
    typename N_B test(); // use of the typedef in the return type
};

template <class T>
typename B<T>::N_B B<T>::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 &akey, const T &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 &akey, const T &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 &akey, const T &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 &akey, const T &avalue)
 870: { return QHash<Key, T>::insertMulti(akey, avalue); }

のあたり.これを,リリースノートの状況に照らし合わせると

class Aclass QMap/QHash
class Bclass QMultiMap/QMultiHash
N_Aiterator
test()replace()/insert()

となるので,QMultiMap の修正は,typedef で QMultiMap::QMapItr 型を追加.inser(),replace()の返り値を QMultiMap::QMapItr 型にすると言うことになる.

class QMultiMap : public QMap<Key, T>
{
public:
  typedef QMap<Key, T>::iterator QMapItr;  // rename
  inline typename QMapItr insert( const Key &key, const T &value );
}

template <class Key, class T> 
Q_INLINE_TEMPLATE Q_TYPENAME QMultiMap<class Key, class T>::QMapItr 
 QMultiMap<class Key, class T>::insert(const Key &akey, const T &avalue)
{ return QMap<Key, T>::insert(akey, avalue); }

それで,QMultiMap::replace, QMultiHash::insert, QMultiHash::replace も同様にしてみたのをqt4-multi-map-hash-msvc8-sp1.diff においておくのですが,patch の使い方が良くわからないので,使いたい人は,diffファイルの中身を見て適当に解釈してどうぞ.

mt/d061216_qt4_msvc8_sp1_problem.txt · 最終更新: 2008/09/01 08:06 (外部編集)
 
 
©2008 Another cool website by 80KV