Std::map between enum and alias to function pointer taking std::vector argument fails to compile

Hello experts,

I am writing a class that uses a map between an enum and a function pointer. As an example:

class Test {
    public:
        enum A {
            kPlus,
            kMinus,
            kMultiply
        };
        using testFunc= TH1D* (Test::*)(std::vector<TH1D*>);
        
        Test() {
            mp.insert(std::make_pair(kPlus,&Test::addHists));
            mp.insert(std::make_pair(kMinus,&Test::subtractHists));
            mp.insert(std::make_pair(kMultiply,&Test::multiplyHists));
        }
        ~Test();
        TH1D* addHists(std::vector<TH1D*> inhists) {
            TH1D* reth = inhists[0];
            inhists.erase(inhists.begin());
            for(size_t i = 0;i<inhists.size();++i){
                reth->Add(inhists[i]);
            }
            return reth;
        }
        TH1D* subtractHists(std::vector<TH1D*> inhists) {
            TH1D* reth = inhists[0];
            inhists.erase(inhists.begin());
            for(size_t i = 0;i<inhists.size();++i){
                reth->Add(inhists[i],-1);
            }
            return reth;
        }
        TH1D* multiplyHists(std::vector<TH1D*> inhists) {
            TH1D* reth = inhists[0];
            inhists.erase(inhists.begin());
            for(size_t i = 0;i<inhists.size();++i){
                reth->Multiply(inhists[i]);
            }
            return reth;
        }
    private:
        std::map<A,testFunc> mp;
};

However, when trying to compile using .L test.cxx+, I get an error

root [0] .L test.cxx+
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/emilgormnielsen/PhD/Analysis/O2Flow/./test_cxx.so
/Users/emilgormnielsen/PhD/Analysis/O2Flow/test_cxx_ACLiC_dict.cxx:124:107: error: expected ')'
   static TGenericClassInfo *GenerateInitInstanceLocal(const map<Test::A,TH1D*(Test::*)(std::vector<TH1D>*>*)
                                                                                                          ^
/Users/emilgormnielsen/PhD/Analysis/O2Flow/test_cxx_ACLiC_dict.cxx:124:88: note: to match this '('
   static TGenericClassInfo *GenerateInitInstanceLocal(const map<Test::A,TH1D*(Test::*)(std::vector<TH1D>*>*)
                                                                                       ^
/Users/emilgormnielsen/PhD/Analysis/O2Flow/test_cxx_ACLiC_dict.cxx:124:110: error: expected '>'
   static TGenericClassInfo *GenerateInitInstanceLocal(const map<Test::A,TH1D*(Test::*)(std::vector<TH1D>*>*)
                                                                                                             ^
/Users/emilgormnielsen/PhD/Analysis/O2Flow/test_cxx_ACLiC_dict.cxx:124:65: note: to match this '<'
   static TGenericClassInfo *GenerateInitInstanceLocal(const map<Test::A,TH1D*(Test::*)(std::vector<TH1D>*>*)
                                                                ^
/Users/emilgormnielsen/PhD/Analysis/O2Flow/test_cxx_ACLiC_dict.cxx:125:4: error: expected ')'
   {
   ^
/Users/emilgormnielsen/PhD/Analysis/O2Flow/test_cxx_ACLiC_dict.cxx:124:55: note: to match this '('
   static TGenericClassInfo *GenerateInitInstanceLocal(const map<Test::A,TH1D*(Test::*)(std::vector<TH1D>*>*)
                                                      ^
/Users/emilgormnielsen/PhD/Analysis/O2Flow/test_cxx_ACLiC_dict.cxx:156:1: error: expected function body after function declarator
} // end of namespace ROOT
^
/Users/emilgormnielsen/PhD/Analysis/O2Flow/test_cxx_ACLiC_dict.cxx:267:2: error: expected '}'
}
 ^
/Users/emilgormnielsen/PhD/Analysis/O2Flow/test_cxx_ACLiC_dict.cxx:114:16: note: to match this '{'
namespace ROOT {
               ^
5 errors generated.

This error only occurs when using std::vector as input in the function pointer alias and it seems the TGenericClassInfo class cannot parse the <> from vector type declaration.

Can anything be changed in my code to resolve this error, or will I have to use a raw array of histograms as a workaround?

I am using ROOT 6.30.01 on macOS Sonoma 14.5 on an intel MacBook

Sincerely,
Emil

Hi @enielsen!

Function pointers don’t work well with ROOT IO. You should exclude the relevant data members from the IO by adding the special //! comment, which you probably don’t use anyway:

class Test {
...
    private:
        std::map<A,testFunc> mp; //!
};

I hope this helps!

Cheers,
Jonas

Hi Jonas,

That did the trick! Thanks for the help.

Sincerely,
Emil

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.