How to define a C++ map

Hi,
I’m trying to store information in a C++ map (I’m new to C++ and ROOT), but I’m struggling. If I do:

map<Char_t, Int_t> myMap = {{'a',2}, {'b', 3}};

I get:

Syntax Error: map<Char_t,Int_t> myMap= C:\Users\acgc9\Desktop\CorrientesDeFuga.c(11)

Thanks!


Please read tips for efficient and successful posting and posting code

ROOT Version: 5.34/38
Platform: Windows 11
Compiler: CINT/ROOT C/C++ Interpreter version 5.18.00, July 2, 2010


You are using an old ROOT 5(.34/38) version and face its (CINT interpreter) limitations.

Try to play with the latest ROOT 6 release (which uses the CLING interpreter).

Thanks for reply. If I use 6.24/06 (I have this ROOT version installed in Debian), now the line:

map<char, int> myMap = {{"A",2}, {"B", 3}};

Produces:

In file included from input_line_33:1:
/mnt/c/Users/acgc9/Desktop/CorrientesDeFuga.c:10:17: error: no matching constructor for initialization of 'map<char, int>'
        map<char, int> myMap = {{"A",2}, {"B", 3}};
                       ^       ~~~~~~~~~~~~~~~~~~~
/usr/include/c++/10/bits/stl_map.h:194:7: note: candidate constructor not viable: cannot convert initializer list argument to 'const std::less<char>'
      map(const _Compare& __comp,
      ^
/usr/include/c++/10/bits/stl_map.h:228:7: note: candidate constructor not viable: no known conversion from 'const char [2]' to 'std::pair<const char, int>' for 1st argument
      map(initializer_list<value_type> __l,
      ^
/usr/include/c++/10/bits/stl_map.h:240:7: note: candidate constructor not viable: cannot convert initializer list argument to 'const std::map<char, int, std::less<char>, std::allocator<std::pair<const char, int> > >'
      map(const map& __m, const allocator_type& __a)
      ^
/usr/include/c++/10/bits/stl_map.h:244:7: note: candidate constructor not viable: cannot convert initializer list argument to 'std::map<char, int, std::less<char>, std::allocator<std::pair<const char, int> > >'
      map(map&& __m, const allocator_type& __a)
      ^
/usr/include/c++/10/bits/stl_map.h:250:7: note: candidate constructor not viable: no known conversion from 'const char [2]' to 'std::pair<const char, int>' for 1st argument
      map(initializer_list<value_type> __l, const allocator_type& __a)
      ^
/usr/include/c++/10/bits/stl_map.h:273:2: note: candidate template ignored: couldn't infer template argument '_InputIterator'
        map(_InputIterator __first, _InputIterator __last)
        ^
/usr/include/c++/10/bits/stl_map.h:256:2: note: candidate constructor template not viable: requires 3 arguments, but 2 were provided
        map(_InputIterator __first, _InputIterator __last,
        ^
/usr/include/c++/10/bits/stl_map.h:290:2: note: candidate constructor template not viable: requires at least 3 arguments, but 2 were provided
        map(_InputIterator __first, _InputIterator __last,
        ^
/usr/include/c++/10/bits/stl_map.h:207:7: note: candidate constructor not viable: requires 1 argument, but 2 were provided
      map(const map&) = default;
      ^
/usr/include/c++/10/bits/stl_map.h:215:7: note: candidate constructor not viable: requires 1 argument, but 2 were provided
      map(map&&) = default;
      ^
/usr/include/c++/10/bits/stl_map.h:236:7: note: candidate constructor not viable: requires single argument '__a', but 2 arguments were provided
      map(const allocator_type& __a)
      ^
/usr/include/c++/10/bits/stl_map.h:185:7: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
      map() = default;

In C++, "A" is a character string, while 'A' is a single character.

Maybe you can help me also, switching to ROOT 6 now causes another problem in the full code:

	Int_t n = 6;
	
	Double_t x[n] = {10, 20, 30, 40, 50, 60};

Gives

/mnt/c/Users/acgc9/Desktop/CorrientesDeFuga.c:17:13: error: variable-sized object may not be initialized
        Double_t x[n];

Either:

const UInt_t n = 6;
Double_t x[n] = {10, 20, 30, 40, 50, 60};

or:

Double_t x[] = {10, 20, 30, 40, 50, 60};
const UInt_t n = sizeof(x) / sizeof(Double_t);

Ok, so that was a test map, now the expected one:

map<float, double> data = {{25.0, {14.0, 16.0, 18.0, 19.67, 21.33, 22.67}}};

Gives:

In file included from input_line_52:1:
/mnt/c/Users/acgc9/Desktop/CorrientesDeFuga.c:14:21: error: no matching constructor for initialization of 'map<float, double>'
        map<float, double> data = {{25.0, {14.0, 16.0, 18.0, 19.67, 21.33, 22.67}}};
                           ^      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/10/bits/stl_map.h:194:7: note: candidate constructor not viable: cannot convert initializer list argument to 'const std::less<float>'
      map(const _Compare& __comp,
      ^
/usr/include/c++/10/bits/stl_map.h:207:7: note: candidate constructor not viable: cannot convert initializer list argument to 'const std::map<float, double, std::less<float>, std::allocator<std::pair<const float, double> > >'
      map(const map&) = default;
      ^
/usr/include/c++/10/bits/stl_map.h:215:7: note: candidate constructor not viable: cannot convert initializer list argument to 'std::map<float, double, std::less<float>, std::allocator<std::pair<const float, double> > >'
      map(map&&) = default;
      ^
/usr/include/c++/10/bits/stl_map.h:228:7: note: candidate constructor not viable: no known conversion from 'double' to 'std::pair<const float, double>' for 1st argument
      map(initializer_list<value_type> __l,
      ^
/usr/include/c++/10/bits/stl_map.h:236:7: note: candidate constructor not viable: cannot convert initializer list argument to 'const std::map<float, double, std::less<float>, std::allocator<std::pair<const float, double> > >::allocator_type' (aka 'const std::allocator<std::pair<const float, double> >')
      map(const allocator_type& __a)
      ^
/usr/include/c++/10/bits/stl_map.h:256:2: note: candidate constructor template not viable: requires 3 arguments, but 1 was provided
        map(_InputIterator __first, _InputIterator __last,
        ^
/usr/include/c++/10/bits/stl_map.h:273:2: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
        map(_InputIterator __first, _InputIterator __last)
        ^
/usr/include/c++/10/bits/stl_map.h:290:2: note: candidate constructor template not viable: requires at least 3 arguments, but 1 was provided
        map(_InputIterator __first, _InputIterator __last,
        ^
/usr/include/c++/10/bits/stl_map.h:185:7: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
      map() = default;
      ^
/usr/include/c++/10/bits/stl_map.h:240:7: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
      map(const map& __m, const allocator_type& __a)
      ^
/usr/include/c++/10/bits/stl_map.h:244:7: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
      map(map&& __m, const allocator_type& __a)
      ^
/usr/include/c++/10/bits/stl_map.h:250:7: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
      map(initializer_list<value_type> __l, const allocator_type& __a)

The idea of this is to store {temperature, dependent variables} in a map and then plot them accessing the map with a for loop.

Have you tried with something like this? I vaguely Remember that for the map initialization with a = It was throwing issues.

const map< Year, float> L0Calo_ECAL_realET_Thresholds{ 
           { Year::Y2011 , 2500.},
           { Year::Y2012 , 3000.},
           { Year::Y2015 , 3000.},
           { Year::Y2016 , 2700.},
           { Year::Y2017 , 2700.},
           { Year::Y2018 , 2400.}
        };

Here Year Is Just a enum class of my analysis code

Thanks for your replies Renato,
Unfortunately, the problem persists

map<float, double> data {{25.0, {14.0, 16.0, 18.0, 19.67, 21.33, 22.67}}};

And

In file included from input_line_39:1:
/mnt/c/Users/acgc9/Desktop/test.c:7:21: error: no matching constructor for initialization of 'map<float, double>'
        map<float, double> data {{25.0, {14.0, 16.0, 18.0, 19.67, 21.33, 22.67}}};
                           ^    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/10/bits/stl_map.h:194:7: note: candidate constructor not viable: cannot convert initializer list argument to 'const std::less<float>'
      map(const _Compare& __comp,
      ^
/usr/include/c++/10/bits/stl_map.h:207:7: note: candidate constructor not viable: cannot convert initializer list argument to 'const std::map<float, double, std::less<float>, std::allocator<std::pair<const float, double> > >'
      map(const map&) = default;
      ^
/usr/include/c++/10/bits/stl_map.h:215:7: note: candidate constructor not viable: cannot convert initializer list argument to 'std::map<float, double, std::less<float>, std::allocator<std::pair<const float, double> > >'
      map(map&&) = default;
      ^
/usr/include/c++/10/bits/stl_map.h:228:7: note: candidate constructor not viable: no known conversion from 'double' to 'std::pair<const float, double>' for 1st argument
      map(initializer_list<value_type> __l,
      ^
/usr/include/c++/10/bits/stl_map.h:236:7: note: candidate constructor not viable: cannot convert initializer list argument to 'const std::map<float, double, std::less<float>, std::allocator<std::pair<const float, double> > >::allocator_type' (aka 'const std::allocator<std::pair<const float, double> >')
      map(const allocator_type& __a)
      ^
/usr/include/c++/10/bits/stl_map.h:256:2: note: candidate constructor template not viable: requires 3 arguments, but 1 was provided
        map(_InputIterator __first, _InputIterator __last,
        ^
/usr/include/c++/10/bits/stl_map.h:273:2: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
        map(_InputIterator __first, _InputIterator __last)
        ^
/usr/include/c++/10/bits/stl_map.h:290:2: note: candidate constructor template not viable: requires at least 3 arguments, but 1 was provided
        map(_InputIterator __first, _InputIterator __last,
        ^
/usr/include/c++/10/bits/stl_map.h:185:7: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
      map() = default;
      ^
/usr/include/c++/10/bits/stl_map.h:240:7: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
      map(const map& __m, const allocator_type& __a)
      ^
/usr/include/c++/10/bits/stl_map.h:244:7: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
      map(map&& __m, const allocator_type& __a)
      ^
/usr/include/c++/10/bits/stl_map.h:250:7: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
      map(initializer_list<value_type> __l, const allocator_type& __a)
      ^

I also tried to add const before map<..., but no changes.

try map< float, vector<double>>
You are passing a pair of KEY=float , VALUE= a vector of doubles

about your original thread :

root [6] std::map<std::string, int> myMap{{"A",2}, {"B", 3}}
root [7] std::map<std::string, int> myMap2 = {{"A",2}, {"B", 3}}
(std::map<std::string, int> &) { "A" => 2, "B" => 3 }

both works

1 Like

So finally,

void test2()
{
	
	map<char, int> myMap = {{'A',2}, {'B', 3}};
	cout << myMap['A'] << endl;
	
	map<float, vector<double>> data{{25.0, {14.0, 16.0, 18.0, 19.67, 21.33, 22.67}}};
}

works.
Thanks @RENATO_QUAGLIANI !

So, this is not directly related to my question, not sure if should create a new one, but:

void test2()
{
	
	map<char, int> myMap = {{'A',2}, {'B', 3}};
	cout << myMap['A'] << endl;
	
	map<float, vector<double>> data{{25.0, {14.0, 16.0, 18.0, 19.67, 21.33, 22.67}}};
	data[25.0];
	
	Double_t volts[] = {10, 20, 30, 40, 50, 60};

	TCanvas* c1 = new TCanvas("c1", "test", 640, 480);
	TGraph *graph1 = new TGraph(6, volts, data[25.0]);
	graph1 -> Draw("ap");
}

Gives an error:

In file included from input_line_11:1:
/mnt/c/Users/acgc9/Desktop/test2.c:35:23: error: no matching constructor for initialization of 'TGraph'
        TGraph *graph1 = new TGraph(6, volts, data[25.0]);
                             ^      ~~~~~~~~~~~~~~~~~~~~
/mnt/d/Debian/ROOT/ROOT6.24.06/include/TGraph.h:81:4: note: candidate constructor not viable: no known conversion from 'std::map<float, std::vector<double, std::allocator<double> >, std::less<float>, std::allocator<std::pair<const float, std::vector<double, std::allocator<double> > > > >::mapped_type' (aka 'std::vector<double, std::allocator<double> >') to 'const Double_t *' (aka 'const double *') for 3rd argument
   TGraph(Int_t n, const Double_t *x, const Double_t *y);
   ^
/mnt/d/Debian/ROOT/ROOT6.24.06/include/TGraph.h:79:4: note: candidate constructor not viable: no known conversion from 'Double_t [6]' to 'const Int_t *' (aka 'const int *') for 2nd argument
   TGraph(Int_t n, const Int_t *x, const Int_t *y);
   ^
/mnt/d/Debian/ROOT/ROOT6.24.06/include/TGraph.h:80:4: note: candidate constructor not viable: no known conversion from 'Double_t [6]' to 'const Float_t *' (aka 'const float *') for 2nd argument
   TGraph(Int_t n, const Float_t *x, const Float_t *y);
   ^
/mnt/d/Debian/ROOT/ROOT6.24.06/include/TGraph.h:88:4: note: candidate constructor not viable: no known conversion from 'int' to 'const char *' for 1st argument
   TGraph(const char *filename, const char *format="%lg %lg", Option_t *option="");
   ^
/mnt/d/Debian/ROOT/ROOT6.24.06/include/TGraph.h:84:4: note: candidate constructor not viable: requires 2 arguments, but 3 were provided
   TGraph(const TVectorF &vx, const TVectorF &vy);
   ^
/mnt/d/Debian/ROOT/ROOT6.24.06/include/TGraph.h:85:4: note: candidate constructor not viable: requires 2 arguments, but 3 were provided
   TGraph(const TVectorD &vx, const TVectorD &vy);
   ^
/mnt/d/Debian/ROOT/ROOT6.24.06/include/TGraph.h:87:4: note: candidate constructor not viable: requires at most 2 arguments, but 3 were provided
   TGraph(const TF1 *f, Option_t *option="");
   ^
/mnt/d/Debian/ROOT/ROOT6.24.06/include/TGraph.h:78:4: note: candidate constructor not viable: requires single argument 'n', but 3 arguments were provided
   TGraph(Int_t n);
   ^
/mnt/d/Debian/ROOT/ROOT6.24.06/include/TGraph.h:82:4: note: candidate constructor not viable: requires single argument 'gr', but 3 arguments were provided
   TGraph(const TGraph &gr);
   ^
/mnt/d/Debian/ROOT/ROOT6.24.06/include/TGraph.h:86:4: note: candidate constructor not viable: requires single argument 'h', but 3 arguments were provided
   TGraph(const TH1 *h);
   ^
/mnt/d/Debian/ROOT/ROOT6.24.06/include/TGraph.h:77:4: note: candidate constructor not viable: requires 0 arguments, but 3 were provided
   TGraph();
   ^

Probably this is due to my lack of knowledge about C++ vectors.

I think TGraphs accepts arrays or TVector as input.
Try

TGraph(6, volts, data[25.0].data());

See std::vector - cppreference.com

Do you mean this:

/* Funtions declaration */


/*
TGraphErrors* fill_graph(Double_t* x, Double_t* y, Double_t* ex, Double_t* ey, int markerStyle, int markerColor, TMultiGraph* mg);
*/

//main
void test2()
{
	
	map<char, int> myMap = {{'A',2}, {'B', 3}};
	cout << myMap['A'] << endl;
	
	map<float, TVector<double>> data{{25.0, {14.0, 16.0, 18.0, 19.67, 21.33, 22.67}}};
	data[25.0];
	
	Double_t volts[] = {10, 20, 30, 40, 50, 60};

	TCanvas* c1 = new TCanvas("c1", "test", 640, 480);
	TGraph *graph1 = new TGraph(6, volts, data[25.0].data());
	graph1 -> Draw("ap");
}
In file included from input_line_8:1:
/mnt/d/Sync1/Desktop/test2.c:15:20: error: expected '>'
        map<float, TVector<double>> data{{25.0, {14.0, 16.0, 18.0, 19.67, 21.33, 22.67}}};
                          ^
/mnt/d/Sync1/Desktop/test2.c:16:2: error: use of undeclared identifier 'data'
        data[25.0];
        ^
/mnt/d/Sync1/Desktop/test2.c:21:40: error: use of undeclared identifier 'data'
        TGraph *graph1 = new TGraph(6, volts, data[25.0].data());
                                              ^

Not sure how to build a TVector

Keep the map<float, vector<double>>
And use still
data[25.0].data()

You can also use

vector<double> volts{10, 20, 30, 40, 50, 60};
TGraph *graph1 = new TGraph(volts.size(), volts.data(), data[25.0].data());