2007年9月27日星期四

解决Visual Studio 2005 SP1编译QT代码的BUG

解决Visual Studio 2005 SP1编译QT代码的BUG

产品:QT 4.1.4 & QT 4.2.2
平台:Visual Studio 2005 Service Pack 1 (SP1)
错误:error C2244: unable to match function definition to an existing declaration

现象:
在qmap.h头文件中出现:error C2244: 'QMultiMap::insert' : unable to match function definition to an existing declaration
(据说在qhash.h中也会出现)

参考URL:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=214100

原因:编译器升级后,分不清嵌套类型的名字是指哪一个,哪怕它们很明显地是同一个类型。例如,如下代码就会引发此错误:

template
class Foo
{
public:
typedef int NestedType;
};

template
class Bar : public Foo
{
public:
typename Foo::NestedType test();
};

template
typename Foo::NestedType Bar::test() // this is where the error lies
{
return 0;
}

微软的解释:
The problem is due to the use of Foo and Bar on the line above; the compiler cannot figure out the relationship between the two template parameters even though they are clearly the same. The workaround is to add a typedef for the NestedType of Bar and use that in the implementation of test

解决方法:
在子类型中再次定义嵌套类型的名字

例如,对于QMultiMap,就是这样子

template
class QMultiMap : public QMap
{
public:
/////////////////////////////////////////////////////////////////////////
//Modified by Kenny
//Purpose: fixed the compiling-time error of Visual Studio 2005 SP1
//Ref:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=214100
typedef typename QMap::iterator QMapIteratorType;
//End of modification
/////////////////////////////////////////////////////////////////////////
QMultiMap() {}
QMultiMap(const QMap &other) : QMap(other) {}

inline QMapIteratorType replace(const Key &key, const T &value);
inline QMapIteratorType insert(const Key &key, const T &value);

inline QMultiMap &operator+=(const QMultiMap &other)
{ unite(other); return *this; }
inline QMultiMap operator+(const QMultiMap &other) const
{ QMultiMap result = *this; result += other; return result; }

private:
T &operator[](const Key &key);
const T operator[](const Key &key) const;
};

/////////////////////////////////////////////////////////////////////////////
//Modified by Kenny
//Purpose: fixed the compiling-time error of Visual Studio 2005 SP1
//Ref:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=214100
template
Q_INLINE_TEMPLATE Q_TYPENAME QMultiMap::QMapIteratorType QMultiMap::replace(const Key &akey, const T &avalue)
{ return QMap::insert(akey, avalue); }

template
Q_INLINE_TEMPLATE Q_TYPENAME QMultiMap::QMapIteratorType QMultiMap::insert(const Key &akey, const T &avalue)
{ return QMap::insertMulti(akey, avalue); }

//The old code is commented out as the following lines

//template
//Q_INLINE_TEMPLATE Q_TYPENAME QMap::iterator QMultiMap::replace(const Key &akey, const T &avalue)
//{ return QMap::insert(akey, avalue); }
//
//template
//Q_INLINE_TEMPLATE Q_TYPENAME QMap::iterator QMultiMap::insert(const Key &akey, const T &avalue)
//{ return QMap::insertMulti(akey, avalue); }

//End of modification
/////////////////////////////////////////////////////////////////////////////

没有评论: