Greetings,
I must use root 5.34.36 for the software.
In a code I make a map(pair<int, int>,TH2D)
When I try to fill the TH2D I get error
/Users/michaelkunkel/WORK/HADESPANDA/Analysis/./test.C:53:17: error: no matching member function for call to 'Fill'
res->second.Fill(1.,2.);
~~~~~~~~~~~~^~~~
/usr/local/Cellar/root/5.34.36_2/include/root/TH2.h:70:21: note: candidate function not viable: no known conversion from 'const TH2D' to 'TH2' for
object argument
virtual Int_t Fill(Double_t x, Double_t y);
^
/usr/local/Cellar/root/5.34.36_2/include/root/TH2.h:63:13: note: candidate function not viable: no known conversion from 'const TH2D' to 'TH2' for
object argument
...
...
I am not trying to save the map to a tree, just use it as a logical container. The Write() and GetTitle() methods work.
Here is a MWE
#include <iostream>
#include <map>
#include <TH2.h>
#include <TH2D.h>
#include <TH1.h>
#include <TF2.h>
std::map<pair<int, int>, TH2D> myMap;
void test(){
double tdcmin = -850, tdcmax = -350;
int ntdcbins = 250;
TH2D *t_vs_t;
for (int i = 1; i<=47; i=i+2) {
t_vs_t = new TH2D (Form("t%d_vs_t%d",i,i+1), Form("t%d_vs_t%d",i,i+1),ntdcbins, tdcmin, tdcmax, ntdcbins, tdcmin, tdcmax);
myMap[std::make_pair(i,i+1)] = *t_vs_t;
}
for(map<pair<int, int>, TH2D>::const_iterator it = myMap.begin(); it != myMap.end(); ++it)
{
std::cout << it->first.first << " " << it->first.second << " " << it->second.GetTitle() << "\n"; //works
//it->second.Write(); //works
}
map<pair<int, int>, TH2D>::const_iterator res;
res = myMap.find(std::make_pair(1,2));
if(res != myMap.end()){
res->second.Fill(1.,2.); //does not work
cout << res->second.GetTitle()<< "\n"; //works
}
}
Any guidance is appreciated.
Why not use pointers and avoid the copy constructors?
#include <iostream>
#include <map>
#include <TH2D.h>
void test(){
const double tdcmin = -850, tdcmax = -350;
const int ntdcbins = 250;
std::map<pair<int, int>, TH2D*> myMap;
for (int i = 1; i<=47; i=i+2) {
myMap[std::make_pair(i,i+1)] = new TH2D (Form("t%d_vs_t%d",i,i+1),
Form("t%d_vs_t%d",i,i+1),ntdcbins, tdcmin, tdcmax, ntdcbins, tdcmin, tdcmax);
}
for(map<pair<int, int>, TH2D*>::const_iterator it = myMap.begin(); it != myMap.end(); ++it) {
std::cout << it->first.first << " " << it->first.second << " " << it->second->GetTitle() << "\n";
}
map<pair<int, int>, TH2D*>::const_iterator res;
res = myMap.find( std::make_pair(1,2) );
if(res != myMap.end()) {
res->second->Fill(1.,2.);
cout << res->second->GetTitle() << "\n";
}
}
EDIT @behrenhoff explains what is happening below.
You are using a const_iterator but Fill obviously isn’t const. That is also what your error message says: no known conversion from 'const TH2D' to 'TH2'.
Solutions:
a) (the obvious one) use a non-const iterator
b) (what I would suggest) change your map. Make the value a TH2* instead of a TH2D, i.e. std::map<pair<int, int>, TH2*> myMap; You can then remove the variable t_vs_t and your loop can look like this:
for (int i = 1; i<=47; i=i+2) {
myMap[std::make_pair(i,i+1)] = new TH2D(Form("t%d_vs_t%d",i,i+1), Form("t%d_vs_t%d",i,i+1),
ntdcbins, tdcmin, tdcmax,
ntdcbins, tdcmin, tdcmax);
}
This will also get rid of the useless copy of the histogram you’re making in the myMap[...] = *t_vs_t line.
And finally the histograms in this map can also be filled using the map’s const_iterator because it will just make the pointer const, i.e. accessing it->second is accessing a TH2* const, not a const TH2*.
///
Final comment: I find it a bit strange that you have a pair as map key. At least in this code the pair is always (i,i+1), thus it would be sufficient to use i as key.
Edit: @ksmith: you obviously had the same idea and were a few seconds faster 
Thanks everyone. Clears everything up.