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