std :: map ::为不正确的value_type插入无限循环

时间:2013-07-19 12:58:17

标签: c++ visual-c++ stl

我最近在我刚写的一些代码中遇到了一个非常愚蠢的错误。花了一些时间查看调试器后,我发现了一些我觉得很奇怪的东西。请考虑以下不正确但非常简单的代码。

#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拒绝这个代码(应该这样)。

1 个答案:

答案 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>> ...

这在一定程度上回答了为什么它在没有抱怨的情况下进行编译......但它并没有解释你的无限循环......不知道该说些什么:)