Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Initializer Lists with std::map

I asked an earlier question, which got off-topic in CString and Unicode issues.
I've now reduced my example to namespace std and cout (instead of printf).
But the core problem still remains.

This is related to, but separate from the question nominated as a duplicate. That question is about maps-in-maps, and is over 2 years old, with the note that the issue is a priority for the compiler team. (Clearly it is not a priority)
This question is worthy of staying open

Am I using the Initializers properly?
Is there any simple way to fix this without a major workaround?
(This is a minimal example based on a much more complex program)

#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;
}

Output

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

You can see only the final string "Report" survived.

It really looks to me like the intializer list for std::map is just broken.

I'm using Microsoft Visual Studio 2013, with Unicode.
This happens in both Debug and Release builds, with Optimizations Disabled or /O2 The same code works fine on IDEOne

like image 855
abelenky Avatar asked Nov 05 '15 19:11

abelenky


1 Answers

At Slava's insistence, I worked with ctors to find an easy fix:

#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;
}

However, the original code should have worked, and apparently is an acknowledged bug by Microsoft.

like image 133
abelenky Avatar answered Sep 29 '22 19:09

abelenky