简体   繁体   中英

How to populate map of string and pair of vectors of double

What is the best way to populate with values this type?

typedef std::map<std::string, std::pair<std::vector<double>, std::vector<double>>> buf;

So, I need something like this:

(“Label”, {1,2,3}, {100,200,300})

Thank you in advance!

UP: So, I came to this. But it looks not very nice I think:

double a[] = {0.1, 0.2};
double b[] = {0.0, 0.0};
foo.insert( make_pair("box", make_pair(vector<double>(a, a + sizeof(a) / sizeof(a[0])), vector<double>(b, b + sizeof(b) / sizeof(b[0]))) ) );

You can use insert

typedef std::map<std::string, std::pair<std::vector<double>, std::vector<double>>> buf;

int main()
{
    buf foo;
    foo.insert({"Label", {{1,2,3}, {100,200,300}}});
}

Note that you need an enclosing {} to indicate your std::pair .

With lots and lots of braces:

buf my_map {         // <== whole map
    {                // <== next individual map item
        "Label",     // <== key
        {            // <== value
            {1.0, 2.0, 3.0},       // <== value.first
            {100.0, 200.0, 300.0}  // <== value.second
        } 
    }  
};

Which when you put the whole item on one line reads:

buf my_map {
    {"Label", {{1.0, 2.0, 3.0}, {100.0, 200.0, 300.0}}}  
};

if it's C++11 or newer

buf x = {{"Label", {{1,2,3}, {100, 200, 300}}};

EDIT

Without C++11 if you really want to populate with literals (like in your example), create helper function:

template <int N, int M>
std::pair<std::vector<double>, std::vector<double>> build_pair(double(&x)[N], double(&y)[M])
{
    return std::make_pair(std::vector<double>(x, x + N), std::vector<double>(y, y + M));
}

and you can use it:

    double x[] = { 1, 2, 3 };
    double y[] = { 100, 200, 300 };
    b["Label"] = build_pair(x, y);

Just in case you meant that the vectors already exist and you're not initializing the map at the time of construction with literal values, then you'd typically use std::make_pair for creating the pair of vectors, as well as the key/value pair going into the map.

#include <utility>

buf my_map;
my_map.insert(std::make_pair(label, std::make_pair(vector1, vector2)));
typedef std::map<std::string, std::pair<std::vector<double>, std::vector<double>>> buf;

buf mybuf {
    {
        "Label",
        {
            {1,2,3}, {100,200,300}
        }
    },

    {
        "Label2",
        {
            {4,5,6}, {400,500,600}
        }
    }
};

For simplifying the creation of a (with compile-time constants) filled map I created templates like this:

#include <map>
#include <type_traits>
template<typename... Ts>
constexpr auto make_map(Ts&&... ts)
    -> std::map<typename std::common_type_t<Ts...>::first_type,typename std::common_type_t<Ts...>::second_type>
{
    return { std::forward<Ts>(ts)... };
}//---------------------------------------------------------

It can be used like this:

using namespace std;
auto myDict = make_map(make_pair(666,string("the number of the beast"))
                      ,make_pair(667,string("the neighbor of the beast"))
                      );

creating myDict as a "map< int,string >".

Or in your case use it like this:

using namespace std;
auto myDict = make_map(make_pair(string("label")
                                , make_pair(make_vector(1.,2.,3.)
                                           ,make_vector(100.,200.,300.)
                                           )
                                )
                      );

("make_vector" can be defined pretty similar to "make_map")

The make_... approach is helpful (or at least "to me seems to be") because it omits an explicit template type declaration by taking the type(s) from the parameters.

Maybe this is somehow helpful to others too (or at least inspiring :-))...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM