5

I have the following program compiled at different compiler,and get different behavior ,

Source :

#include <iostream>
#include <sstream>
#include <unordered_map>

using namespace std ;

std::unordered_map<std::string,std::string> mymap;
std::unordered_multimap<std::string,std::string> mymultimap;
int main ()
{
    DoAddItem() ;

    std::cout << "mymap contains:";
    for ( auto it = mymap.begin(); it != mymap.end(); ++it )
        std::cout << " " << it->first << ":" << it->second;
    std::cout << std::endl;

    std::cout << "============================================" << std::endl ;
    std::cout << "mymultimap contains:";
    for ( auto it2 = mymultimap.begin(); it2 != mymultimap.end(); ++it2 )
        std::cout << " " << it2->first << ":" << it2->second;
    std::cout << std::endl;
    return 0;
} 

void  DoAddItem() 
{
    std::pair<std::string,std::string> mypair[100]; 
    int idx ;
    std::string s1  ;
    std::string s2  ;
    for(idx=0;idx<10;idx++)
    {
        s1 = string("key") + int2str(idx) ;
        s2 = string("val") + int2str(idx) ;
        mypair[idx] = {s1,s2} ;
        mymap.insert(mypair[idx]) ;
        mymultimap.insert(mypair[idx]) ;
    }//for 
    return ; 
}

Compiled in g++ 4.4.6 in RedHat Linux like :

g++  --std=c++0x unordered_map1.cpp -o unordered_map1.exe 

will get the right answer for mymap and mymultimap , but in MinGw : http://sourceforge.net/projects/mingwbuilds/?source=dlp

Compile it as the following :

g++ -std=gnu++11 unordered_map1.cpp -o unordered_map1.exe

This time , mymap still get the right answer , but mymultimap are all empty , the MinGw g++ version is

g++ (rev1, Built by MinGW-builds project) 4.8.1

I am interesting in c++11 so I download MinGw compiler in my winx , g++ 4.4.6 , my develope compiler , can not compile c++11 for test .

What I missed ? my goal is testing c++11 , Any suggestion is appreciated !!

Edit :

mymultimap.insert(mypair[idx]) ;   //won't work !!
mymultimap.insert(make_pair(s1,s2)) ; //This work !!

After I change my code to make_pair , it works in MinGw and print the right answer for mymultimap ....that is strange to me though ~~

Ali
  • 56,466
  • 29
  • 168
  • 265
barfatchen
  • 1,630
  • 2
  • 24
  • 48
  • there is no error message, OP states multimap is empty when using his code with MinGW –  Jun 11 '13 at 09:10
  • @barfatchen (1) With gnu++11 you also enable gnu extensions, see [What are the differences between -std=c++11 and -std=gnu++11?](http://stackoverflow.com/q/10613126/341970) (2) At some point during the standardization procedure `pair` was broken, I don't remember the exact details. What you see might be related to that. Well, none of these things help you but let's hope someone can answer your question. – Ali Jun 11 '13 at 10:50

1 Answers1

3

BUG FILED http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57619

This is not directly related to mingw. A test case compiled with g++4.8 has the same problem. However, the same test case compiled with g++4.7.2 on ideone does not have this problem. This is a bug in g++4.8 and you should report it (or let me know and I will report it for you).

What is happening:

The call to mymap.insert(mypair[0]); is moving the string out of the std::pair. So, when mymultimap.insert(mypair[0]); is called, the strings have already been moved.

Here is a minimum test case:

std::unordered_map<std::string,std::string> mymap;
std::unordered_multimap<std::string,std::string> mymultimap;
int main ()
{
    std::pair<std::string,std::string> mypair[1]; 
    std::string s1 = std::string("key");
    std::string s2 = std::string("val");
    mypair[0] = {s1,s2};
    mymap.insert(mypair[0]);
    mymultimap.insert(mypair[0]);
    std::cout << "mymultimap contains:";
    for ( auto it2 = mymultimap.begin(); it2 != mymultimap.end(); ++it2 )
        std::cout << " " << it2->first << ":" << it2->second;
}
Jesse Good
  • 50,901
  • 14
  • 124
  • 166
  • Thanks , If you could report this problem to related center , that would be great appreciated !! it is kind of you ~~ – barfatchen Jun 12 '13 at 23:56