tl;dr:凯特的回答中的解决方案对OP有效;解释不正确。有问题的代码实际上是正确的,并且可以在 VS2015 中编译。错误(在VS2013Update 3)是 MS 如何处理 VS2013 RTM 中发现的错误的结果(他们实际上没有通过更新修复它,但他们确实破坏了一些工作代码)。在 VS2015 中已正确修复。
您的代码在 VS2015 中运行良好。据微软称,在VS2013中,
是的,我们在 Update 3 中将这些错误插入到编译器中,因为我们对非静态数据成员初始化的实现不完整。
成员初始化列表中的列表/花括号初始化在 VS2013 中也被破坏。他们的实施的问题是最佳插图 with a vector
,其中有一个initializer_list
构造函数should贪婪地匹配任何使用大括号和可转换参数的初始化,但它失败了:
struct S {
S() : v1{1} {} // C2797, VS2013 RTM incorrectly calls 'vector(size_type)'
std::vector<int> v1;
std::vector<int> v2{1, 2}; // C2797, VS2013 RTM incorrectly calls
// 'vector(size_type, const int &)'
};
编译器很容易退回到正常的重载解析。而不是使用std::initializer_list
构造函数,它调用size_t
构造函数。正如他们的评论所表明的,这是错误的!因此,由于其实现存在缺陷,Microsoft 决定禁用在此上下文中使用支撑初始化的功能。
For a std::string s
,应该没有问题,因为正确的事情s{"duh"}
is打电话std::string(const char*)
,但由于存在缺陷,MS 无论如何都会给出错误。解决方法是明确使用括号代替大括号(或升级到 VS2015),如 Kate 的回答所述。但错误的正确原因如上所述。
这适用于非静态数据成员初始化 (NSDMI) 以及初始化列表。这在这有更多解释Visual C++ 团队博客。至于为什么VS2013一直没有修复:
我们最初计划在 Visual Studio 2013 的更新中修复此错误,但从工程角度来看,正确的做法是避免再次出现混乱并彻底解决初始化的处理问题。但由于需要修改大量的基本代码,彻底修改编译器架构是一项艰巨的任务。我们不能冒险在更新中造成不兼容或大错误尾部,因此 NSDMI 的正确实现只能在主要版本中发布。
显然,该修复已包含在 Visual Studio 2015 中,但永远不会包含在 2013 的更新中。