Dear ROOTers,
in our experiment software we have a piece of code almost identical to the following snippet:
#include <iostream>
#include <vector>
#include "TROOT.h"
#include "TMath.h"
#include "TF1.h"
class MyClass : public TObject {
public:
MyClass();
~MyClass();
double operator()(double* x, double*p){ return x[0]*x[0]; };
std::vector<float> Generate(int nevents){
std::vector<float> vec;
TF1 *f = new TF1("temp_f",this,0,4000,0,"MyClass");
f->SetNpx(4000);
for(int i=0;i<nevents;i++){
vec.push_back(f->GetRandom());
}
delete f;
return vec;
}
};
int main(){
MyClass* testobj;
std::vector<float> vec = testobj->Generate(100);
for(int i=0; i<vec.size(); i++){
std::cout << vec[i] << std::endl;
}
}
which compiled just fine until I accidentally (curse you, Apple!) upgraded XCode to version 9.0.
After checking out commit 9339de9e64 from the master branch (where the fix for XCode 9 was introduced) I recompiled ROOT. Now suddenly the piece of code above does not compile anymore
1 âś— vformato@formato-pc0 /Volumes/AMS_Disk/test/test_TF1
17:42 $ g++ -o test -I `root-config --cflags` test.C
In file included from test.C:6:
/Users/vformato/root/include/TF1.h:370:101: error: type 'MyClass *' cannot be used prior to '::' because it has no
members
using Fnc_t = typename ROOT::Internal::GetFunctorType<decltype(ROOT::Internal::GetTheRightOp(&Func::oper...
^
test.C:17:18: note: in instantiation of function template specialization 'TF1::TF1<MyClass *>' requested here
TF1 *f = new TF1("temp_f",this,0,4000,0,"MyClass");
^
In file included from test.C:6:
In file included from /Users/vformato/root/include/TF1.h:35:
/Users/vformato/root/include/Math/ParamFunctor.h:125:17: error: no matching function for call to object of type
'MyClass'
return (*f)((T*)x, (double*)p);
^~~~
/Users/vformato/root/include/Math/ParamFunctor.h:95:45: note: in instantiation of member function
'ROOT::Math::ParamFunctorHandler<ROOT::Math::ParamFunctorTempl<int>, MyClass *>::FuncEvaluator<MyClass *,
int>::EvalConst' requested here
return FuncEvaluator<Func, EvalType>::EvalConst(fFunc,x,p);
^
/Users/vformato/root/include/Math/ParamFunctor.h:73:4: note: in instantiation of member function
'ROOT::Math::ParamFunctorHandler<ROOT::Math::ParamFunctorTempl<int>, MyClass *>::operator()' requested here
ParamFunctorHandler(const Func & fun) : fFunc(fun) {}
^
/Users/vformato/root/include/Math/ParamFunctor.h:304:17: note: in instantiation of member function
'ROOT::Math::ParamFunctorHandler<ROOT::Math::ParamFunctorTempl<int>, MyClass *>::ParamFunctorHandler' requested
here
fImpl(new ParamFunctorHandler<ParamFunctorTempl<T>,Func>(f) )
^
/Users/vformato/root/include/TF1.h:372:51: note: in instantiation of function template specialization
'ROOT::Math::ParamFunctorTempl<int>::ParamFunctorTempl<MyClass *>' requested here
fFunctor = new TF1FunctorPointerImpl<Fnc_t>(ROOT::Math::ParamFunctorTempl<Fnc_t>(f));
^
test.C:17:18: note: in instantiation of function template specialization 'TF1::TF1<MyClass *>' requested here
TF1 *f = new TF1("temp_f",this,0,4000,0,"MyClass");
^
test.C:13:10: note: candidate function not viable: no known conversion from 'int *' to 'double *' for 1st argument
double operator()(double* x, double*p){ return x[0]*x[0]; };
^
In file included from test.C:6:
In file included from /Users/vformato/root/include/TF1.h:35:
/Users/vformato/root/include/Math/ParamFunctor.h:121:17: error: no matching function for call to object of type
'MyClass'
return (*f)(x, p);
^~~~
/Users/vformato/root/include/Math/ParamFunctor.h:91:45: note: in instantiation of member function
'ROOT::Math::ParamFunctorHandler<ROOT::Math::ParamFunctorTempl<int>, MyClass *>::FuncEvaluator<MyClass *,
int>::Eval' requested here
return FuncEvaluator<Func, EvalType>::Eval(fFunc,x,p);
^
/Users/vformato/root/include/Math/ParamFunctor.h:73:4: note: in instantiation of member function
'ROOT::Math::ParamFunctorHandler<ROOT::Math::ParamFunctorTempl<int>, MyClass *>::operator()' requested here
ParamFunctorHandler(const Func & fun) : fFunc(fun) {}
^
/Users/vformato/root/include/Math/ParamFunctor.h:304:17: note: in instantiation of member function
'ROOT::Math::ParamFunctorHandler<ROOT::Math::ParamFunctorTempl<int>, MyClass *>::ParamFunctorHandler' requested
here
fImpl(new ParamFunctorHandler<ParamFunctorTempl<T>,Func>(f) )
^
/Users/vformato/root/include/TF1.h:372:51: note: in instantiation of function template specialization
'ROOT::Math::ParamFunctorTempl<int>::ParamFunctorTempl<MyClass *>' requested here
fFunctor = new TF1FunctorPointerImpl<Fnc_t>(ROOT::Math::ParamFunctorTempl<Fnc_t>(f));
^
test.C:17:18: note: in instantiation of function template specialization 'TF1::TF1<MyClass *>' requested here
TF1 *f = new TF1("temp_f",this,0,4000,0,"MyClass");
^
test.C:13:10: note: candidate function not viable: no known conversion from 'int *' to 'double *' for 1st argument
double operator()(double* x, double*p){ return x[0]*x[0]; };
^
3 errors generated.
Being paranoid I also checked out the HEAD of the master branch and the problem is still there. Googling around I found out this stackoverflow thread that seems to be kinda related, even if I don’t understand how this didn’t happen with the previous clang version.
Any idea how to solve this?
Cheers,
Valerio