Visual Studio 11使用std::map编译时出现错误

6
以下代码可以使用gcc-4.5.1编译,但无法在Visual Studio 11中编译。
#include <map>
#include <array>

typedef std::pair<const unsigned int, std::array<const unsigned int, 4>> pairus;

int main(){

   std::map<const unsigned int, std::array<const unsigned int, 4> > x; 
   std::array<const unsigned int, 4> troll = {1, 2, 3, 4};
   x.insert(pairus(1, troll));

   auto z = x[1];
}

现在,1被映射到std::array<> troll。插入操作正常,程序可以编译通过。但是,当我尝试使用auto z = x[1]获取映射到1的数组troll时,程序会出现以下错误:error C2512: 'std::array<_Ty,_Size>::array' : no appropriate default constructor available

是什么原因导致了GCC和VS11之间的这种行为差异,如何解决?

谢谢。


pairus是什么样子(假设它是一个自定义函数?还是MSVC++中make_pair的别名?)。我怀疑问题可能出在pairus上,因为您发布的代码中没有任何需要默认构造函数的地方。(尽管如果您执行x[k],其中k不在映射中,则需要默认构造函数。) - Corbin
@Corbin:他在主函数上面的自己的代码中定义了pairus。 - Benjamin Lindley
@ScarletAmaranth 对不起,我的确失去了阅读能力,可能持续了几分钟。 - Corbin
1
你尝试过 auto z(x[1]); 吗? - n. m.
请注意,单行代码 std::array<const unsigned int, 4> another_troll; 也会出现相同的错误。无需使用 map。 - Dan Nissenbaum
显示剩余5条评论
2个回答

4

建议改用auto z = *x.find(1);。使用[]操作符需要一个默认可构造类型。实际上,整个容器都需要一个默认可构造类型,因此在尝试不同的实现时,您不能期望除了随机运气之外的任何东西。


你真是个天才!:) 成功了!:) Gcc 似乎知道一些神秘的魔法。谢谢;) - ScarletAmaranth
现在C++11已经过去了,不确定默认构造函数的要求是否适用于整个容器。新地图需要能够容纳可移动类型,但只有部分功能对它们可用。我认为[]运算符不是其中之一。 - Edward Strange

3

由于该类型包含常量,因此无法将其分配。

x[1]试图返回可分配的引用。如果键不存在,它还将为该键构造一个空值。这两个在您的类型中都是无效的。您必须改用find。


gcc为什么会编译这个东西呢 :) ? - ScarletAmaranth
标准只规定了必须的内容,而没有规定允许的内容。某些gcc实现方式在您的特殊情况下不会导致相同的问题,这是允许的。这里没有诊断要求。 - Edward Strange

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接