0

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

#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))whereid可能非常大。它从未引发任何内存异常,但我想它花费了大量时间来分配它(没有失败),这就是它出现循环的原因。因此,似乎 MSVC 很乐意将隐式转换为std::list,但 gcc 不是。这很令人困惑,根据http://www.cplusplus.com/reference/list/list/list/的构造函数std::list都标记为explicit. 看起来错误是 MSVC10,MSVC11 拒绝此代码(应该如此)。

4

1 回答 1

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>>使用上述构造函数进行列表...

这在某种程度上回答了为什么它编译而不抱怨......但它并没有解释你的无限循环......不知道该说什么:)

于 2013-07-19T13:06:03.477 回答