1

以下代码无法使用 Visual Studio 2013 进行编译。它使用 Xcode 6.1 (Clang 3.5) 进行编译。

std::string s1("one");
std::string s2("two");
std::string s3("three");
std::string s4("four");

class X
{
    typedef std::map<std::string, std::string> MyMapType;
    MyMapType map1 = { { s1, s2 }, { s3, s4 } };
    MyMapType map2 = { { std::make_pair(s1, s2) }, { std::make_pair(s3, s4) } };
};

两个声明报告的错误是:

error C2664: 'std::map<std::string,std::string,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>::map(std::initializer_list<std::pair<const _Kty,_Ty>>,const std::less<_Ty> &,const std::allocator<std::pair<const _Kty,_Ty>> &)' : cannot convert argument 2 from 'initializer-list' to 'const std::allocator<std::pair<const _Kty,_Ty>> &'

但是,以下内容会编译:

int main()
{
    typedef std::map<std::string, std::string> MyMapType;
    MyMapType map3 = { { s1, s2 }, { s3, s4 } };

    return 0;
}

请有人可以解释一下。

4

1 回答 1

4

众所周知,Visual C++ 2013 在处理非静态数据成员初始化器和构造器成员初始化器列表中的列表初始化时存在缺陷。它被严重破坏 - 在某些情况下会导致无声的错误代码生成 -他们只是在 Visual Studio 2013 Update 3 中的所有情况下都将其作为编译器错误(发布实际修复显然被认为对于更新来说风险太大)。

您的代码可以使用Microsoft 的在线编译器很好地编译,该编译器运行 Visual C++ 2015 的预览版,所以看起来这个问题已经得到修复。

一种解决方法(在上面链接的 MSDN 页面中注明)也在 RHS 上显式指定类型,这样您实际上就不会对非静态数据成员进行列表初始化。

MyMapType map1 = MyMapType{ { s1, s2 }, { s3, s4 } };
MyMapType map2 = MyMapType{ { std::make_pair(s1, s2) }, { std::make_pair(s3, s4) } };
于 2015-05-06T06:51:45.240 回答