将Initializer Lists与std::map一起使用

Using Initializer Lists with std::map

本文关键字:map 一起 std Initializer Lists      更新时间:2023-10-16

我之前问了一个问题,这个问题偏离了CString和Unicode问题的主题
现在,我已经将示例简化为namespace stdcout(而不是printf
但核心问题仍然存在。

这与指定为重复的问题有关,但与此问题不同。这个问题是关于地图中的地图的,已经有2年多的历史了,请注意,这个问题是编译器团队的优先事项。(显然这不是优先事项)
这个问题值得继续讨论

我是否正确使用初始化程序
有没有什么简单的方法可以在没有主要解决方法的情况下解决这个问题
(这是一个基于更复杂程序的最小示例)

#include <map>
#include <string>
#include <iostream>
struct Params
{
    int         inputType;
    std::string moduleName;
};
int main()
{
    std::map<std::string, Params> options{
        { "Add",       { 30, "RecordLib" } },
        { "Open",      { 40, "ViewLib"   } },
        { "Close",     { 50, "EditLib"   } },
        { "Inventory", { 60, "ControlLib"} },
        { "Report",    { 70, "ReportLib" } }
    };
    for (const auto& pair : options)
    {
        std::cout << "Entry: " << pair.first << " ==> { " << pair.second.moduleName << "    }" << std::endl;
    }
    return 0;
}

输出

Entry:  ==> {  }
Entry: Report ==> {    }

您只能看到最后一个幸存的字符串"Report"

在我看来,std::map的初始化器列表确实被破坏了。

我使用的是带有Unicode的Microsoft Visual Studio 2013
这种情况在DebugRelease构建中都会发生,其中Optimizations Disabled/O2相同的代码在IDEOne

上运行良好

在斯拉瓦的坚持下,我与ctors合作找到了一个简单的解决方案:

#include <map>
#include <string>
#include <iostream>
struct Params
{
    int         inputType;
    std::string moduleName;
    Params(const int n, const std::string& s) :
        inputType(n),
        moduleName(s)
    { }
};
int main()
{
    std::map<std::string, Params> options = {
        { "Add",       Params(30, "RecordLib" ) },
        { "Open",      Params(40, "ViewLib"   ) },
        { "Close",     Params(50, "EditLib"   ) },
        { "Inventory", Params(60, "ControlLib") },
        { "Report",    Params(70, "ReportLib" ) }
    };
    for (const auto& pair : options)
    {
        std::cout << "Entry: " << pair.first << " ==> { " << pair.second.moduleName << "    }" << std::endl;
    }
    return 0;
}

然而,最初的代码应该是有效的,而且显然是微软公认的错误。