1
votes

I need to use STL C++ map to store key value pairs. I need to store more than one data information in stl map. e.g

Need to store DataType,Data and its behavior as(in param/outparam) all in string format. But map always use key value pair

so if I store it like

std::map<map<"int","50",>"behavior">. 

But always it sorts the the data on basis of keys which I dont want. If I use like ..

pair<string, pair<string,string> >;
pair<string, pair<string,string>>("int",("100","in"));

This prompts compile time error!

error C2664: 'std::pair<_Ty1,_Ty2>::pair(const std::pair<_Ty1,_Ty2> &)' : cannot convert parameter 1 from 'const char *' to 'const std::pair<_Ty1,_Ty2> &'

What should be the exact solution of the above problem?

Regards

4
Don't quite understand your problem, but is an std::multimap what you want?Oliver Charlesworth
I think the biggest problem is not C++ or std::map, but understanding the question. And I'm inclined to think (from the little code I see) that Usman doesn't understand it either. "unsorted key-value pair" doesn't make sense. A collection can be sorted, but a single element cannot.MSalters

4 Answers

4
votes

If you don't want ordering, don't use ordered containers like map or set. You could achieve what you're looking for using a class and a vector. The sorted nature of std::map is what makes it efficient to lookup by key. If you want/need unsorted and more hash like behavior for lookups, look at Boost unordered containers. Note that this doesn't guarantee the order in is going to be the order out. I'm assuming you want to preserve the order of the types your putting in the container, the example below will do that.

#include <iostream>
#include <vector>

using namespace std;

class DataBehavior
{
public:
    DataBehavior(const string &type, 
                 const string &data,
                 const string &behavior)
        :type(type), data(data), behavior(behavior)
    {
    }

    const string &getType() const     { return type; }
    const string &getData() const     { return data; }
    const string &getBehavior() const { return behavior; }

private:
    string type;
    string data;
    string behavior;
};

typedef vector<DataBehavior> Ctr;

int main (int argc, char *argv[])
{
    Ctr ctr;
    ctr.push_back(DataBehavior("int",    "50", "behavior"));
    ctr.push_back(DataBehavior("int",    "80", "behavior"));
    ctr.push_back(DataBehavior("string", "25", "behavior2"));

    for (Ctr::const_iterator it = ctr.begin(); it != ctr.end(); ++it)
    {
        cout << "Type: " << it->getType() << "  " 
             << "Data: " << it->getData() << "  "
             << "Behavior: " << it->getBehavior() << "\n";
    }
    return 1;
}
2
votes

You're declaring the variables wrong in the

pair<string, pair<string,string> >;
pair<string, pair<string,string>>("int",("100","in"));

You'd need to do

pair<string, pair<string,string>>("int",pair<string,string>("100","in"));

which is fairly verbose. You could use the make_pair function to significantly shorten that:

make_pair( "int", make_pair( "100", "in" ) );

Also, as the others have said, if you don't want sorted order, use unordered_map from TR1 or Boost. If you're on MS you can use hash_map instead.

1
votes

Need to store DataType,Data and its behavior as(in param/outparam) all in string format. But map always use key value pair

To me it seems you need to use different data structure, e.g.

typedef std::tuple<std::string,               // DataType
                   std::string,               // Data
                   std::string> element_type; // behaviour

// use can replace tuple with sth like: 
//struct element_type {
//    std::string m_DataType;
//    std::string m_Data;
//    std::string m_Behaviour;
//    ... ctors, operators ...
//};
// or even with std::array<std::string, 3>

std::set<element_type> elements_set;

// or

typedef int32_t element_id;

std::map<element_id, element_type> elements_map;

And you've got rather a design problem than a programming one.

1
votes

Why do you use a map in the first place? What do you want to use as lookup key -- the datatype? The value? The "param/outparam" characteristic?

Whatever you want to use as a key should go first, and the rest could be a struct / pointer / string (*urg*) / ... .

So I suggest you give some more thought to your needs and design a datastructure accordingly.