我正在從Linux移植一個相對較大的代碼到Windows(我必須使用Visual Studio 2008)。 我完成了移植並且正在工作,但是我不得不評論一小段代碼,因爲Visual Studio給出了這個錯誤,我無法準確理解原因。 所以,基本上,存在從一個std收集了函子::所有的「項目」是satify一定的條件下,這樣定義的映射:從它繼承C++ VS2008 - 類模板實例化上的奇怪錯誤
/*
* Map collector
*/
template<class TMap>
class CMapCollector
{
public:
typedef typename TMap::value_type tValueType;
CMapCollector(void)
{ }
void operator() (const tValueType& rcValue)
{
if (CheckCondition(rcValue))
mCollector.push(rcValue);
}
bool NextResult(void) const
{
return (!mCollector.empty());
}
tValueType GetResult(void)
{
if (!NextResult())
return tValueType();
tValueType curr_value = mCollector.front();
mCollector.pop();
return curr_value;
}
private:
virtual bool CheckCondition(const tValueType& rcValue) const = 0;
typedef std::queue<tValueType> tCollectorContainer;
tCollectorContainer mCollector;
};
於是,一些收藏家類被定義。 我寫了一個小例子,顯示該錯誤,以便從所有的其他代碼提取它:
/*
* Some class
*/
class CMyClass
{
public:
CMyClass(const int cNum) : mNum(cNum)
{ }
bool DifferentFrom(const int cFrom) const
{
return (Get() != cFrom);
}
bool EqualTo(const int cTo) const
{
return (Get() == cTo);
}
private:
int Get(void) const
{
return mNum;
}
int mNum;
};
/* Some map definition */
typedef std::map<int, CMyClass *> tMyMap;
/*
* Real collectors
*/
class CNoNullCollector : public CMapCollector<tMyMap>
{
private:
bool CheckCondition(const tValueType& rcValue) const
{
return (rcValue.second->DifferentFrom(0));
}
};
class CValueCollector : public CMapCollector<tMyMap>
{
public:
CValueCollector(const int cValue) : mValue(cValue)
{ }
private:
bool CheckCondition(const tValueType& rcValue) const
{
return (rcValue.second->EqualTo(mValue));
}
int mValue;
};
/*
* main
*/
int main(int argc, char *argv[])
{
tMyMap my_map;
/* Insert some value */
my_map.insert(std::make_pair(1, new CMyClass(0)));
my_map.insert(std::make_pair(2, new CMyClass(1)));
my_map.insert(std::make_pair(3, new CMyClass(2)));
my_map.insert(std::make_pair(4, new CMyClass(2)));
my_map.insert(std::make_pair(5, new CMyClass(3)));
/* Collect values */
CNoNullCollector collector = std::for_each(my_map.begin(), my_map.end(), CNoNullCollector());
while (collector.NextResult())
{
CNoNullCollector::tValueType curr_result = collector.GetResult();
/* Do something ... */
}
/* Free memory, not written ... */
return 0;
}
此代碼編譯細的Linux上的g ++(我試圖與兩克++ 4.2和4.9,可在機)。 我也嘗試過使用Visual Studio 2013,它很好。 但是,使用VS2008(以及VS2010)進行編譯時,它會在實例化類模板「CMapCollector」時發生錯誤。 的錯誤是在標準::交換函數,從標準::對叫,在這一點(「實用程序」的文件,一個標準包括):
template<class _Ty> inline
void swap(_Ty& _Left, _Ty& _Right)
{ // exchange values stored at _Left and _Right
if (&_Left != &_Right)
{ // different, worth swapping
_Ty _Tmp = _Left;
_Left = _Right; // <-- error C3892: '_Left' : you cannot assign to a variable that is const
_Right = _Tmp; // <-- error C3892: '_Right' : you cannot assign to a variable that is const
}
}
這是完整的錯誤消息:
c:\program files (x86)\microsoft visual studio 9.0\vc\include\utility(22) : error C3892: '_Left' : you cannot assign to a variable that is const
c:\program files (x86)\microsoft visual studio 9.0\vc\include\utility(31) : see reference to function template instantiation 'void std::swap<_Ty>(_Ty &,_Ty &)' being compiled
with
[
_Ty=int
]
c:\program files (x86)\microsoft visual studio 9.0\vc\include\utility(64) : see reference to function template instantiation 'void std::_Swap_adl<_Ty1>(_Ty &,_Ty &)' being compiled
with
[
_Ty1=int,
_Ty=int
]
c:\program files (x86)\microsoft visual studio 9.0\vc\include\utility(61) : while compiling class template member function 'void std::pair<_Ty1,_Ty2>::swap(std::pair<_Ty1,_Ty2> &)'
with
[
_Ty1=const int,
_Ty2=CMyClass *
]
c:\program files (x86)\microsoft visual studio 9.0\vc\include\deque(518) : see reference to class template instantiation 'std::pair<_Ty1,_Ty2>' being compiled
with
[
_Ty1=const int,
_Ty2=CMyClass *
]
c:\program files (x86)\microsoft visual studio 9.0\vc\include\queue(24) : see reference to class template instantiation 'std::deque<_Ty>' being compiled
with
[
_Ty=std::pair<const int,CMyClass *>
]
c:\users\my_name\desktop\test\test\test.cpp(42) : see reference to class template instantiation 'std::queue<_Ty>' being compiled
with
[
_Ty=std::pair<const int,CMyClass *>
]
c:\users\my_name\desktop\test\test\test.cpp(81) : see reference to class template instantiation 'CMapCollector<TMap>' being compiled
with
[
TMap=tMyMap
]
c:\program files (x86)\microsoft visual studio 9.0\vc\include\utility(23) : error C3892: '_Right' : you cannot assign to a variable that is const
如果我評論中的類模板實例的一部分:
CNoNullCollector collector = std::for_each(my_map.begin(), my_map.end(), CNoNullCollector());
while (collector.NextResult())
{
CNoNullCollector::tValueType curr_result = collector.GetResult();
/* Do something ... */
}
編譯將成功完成。 我知道恆定有一些問題,但我不明白在哪裏。爲什麼g ++成功編譯它?
編輯:
我明白,這件事情涉及到的std ::隊列,性病::地圖的「鑰匙」(因此「第一」的標準::對)是不變根據定義,但我沒有弄清楚如何解決它