我最近在我刚写的一些代码中遇到了一个非常愚蠢的错误。花了一些时间查看调试器后,我发现了一些我觉得很奇怪的东西。请考虑以下不正确但非常简单的代码。
#include <map>
#include <list>
int main() {
std::map<int, std::list<int> > myMap;
// infinite loop, should be std::pair<int, std::list<int> >
myMap.insert(std::pair<int, int>(4, 500000));
return 0;
}
如注释所示,insert
语句会导致程序进入无限循环。原因很明显,我已经传入std::pair<int, int>
对象而不是std::pair<int, std::list<int>>
。不幸的是,这个代码在gcc和MSVC10中编译得非常好。我希望编译器拒绝此代码,因为类型显然不匹配,但它没有。有人会关心解释原因吗?
编辑:它似乎在gcc中工作正常(我使用的网站无法正常工作),但MSVC10仍然接受它。
再次编辑:我认为崩溃的原因是,在我的原始代码中,插入插入如下:
myMap.insert(std::pair<int, int>(4, id))
其中id
可能非常大。它从来没有引起任何内存异常,但我猜它花了很多时间分配它(没有失败),这就是为什么它似乎循环。因此,似乎MSVC很乐意将隐式转换为std::list
,但gcc不是。这是令人困惑的,根据http://www.cplusplus.com/reference/list/list/list/,std::list
的构造函数都标记为explicit
。看起来像一个错误是MSVC10,MSVC11拒绝这个代码(应该这样)。
答案 0 :(得分:2)
我尝试在visual studio 2010中进行编译
Microsoft Visual Studio 2010
Version 10.0.40219.1 SP1Rel
它已编译,但不进入无限循环。相反,它做了以下......
std::map<int, std::list<int> > myMap;
myMap.insert(std::pair<int, int>(4, 5)); // An implicit cast???
std::cout << "mymap now contains " << myMap.size() << " elements.\n";
std::cout << "myMap[4] size is " << myMap[4].size() << '\n';
sel = myMap[4].begin();
end = myMap[4].end();
for(; sel != end; ++sel)
std::cout << *sel << ", ";
std::cout << std::endl;
输出以下内容
mymap now contains 1 elements.
myMap[4] size is 5
0, 0, 0, 0, 0,
所以,我认为这个工作的原因是使用以下默认构造函数创建列表:
explicit list (size_type n, const value_type& val = value_type(),
const allocator_type& alloc = allocator_type());
所以它正在为你创造,4映射到5个元素的列表,每个元素都填充了value_type()。
我的猜测是以某种方式 msvc编译器使用上面的列表构造函数将std::pair<int, int>
转换为std::pair<int, std::list<int>>
...
这在一定程度上回答了为什么它在没有抱怨的情况下进行编译......但它并没有解释你的无限循环......不知道该说些什么:)