Possible bug with TF1?

Hello,
While updating ROOT from 5.34/36 to 6.14/06, I encountered a compilation error, which boils down to the following code (which compiles fine with ROOT5):

#include <TF1.h>
#include <TROOT.h>

class Func1: public TF1 {

 public:

  Func1() : TF1() {};

  Func1(const char *name, void *mfcn, Double_t xmin, Double_t xmax, Int_t npar) :
      TF1(name, (TF1 *) mfcn, xmin, xmax, npar) {
  }
};

int main() {
  return 0;
}

The error log starts as (with g++ 7.3.1 on CentOS6, full log attached):

In file included from test.cpp:1:0:
/data/disk01/home/riviere/aaaaaa/base/root/build/include/TF1.h: In instantiation of ‘static void ROOT::Internal::TF1Builder<Func*>::Build(TF1*, Func*) [with Func = TF1]’:
/data/disk01/home/riviere/aaaaaa/base/root/build/include/TF1.h:361:46:   required from ‘TF1::TF1(const char*, Func, Double_t, Double_t, Int_t, Int_t, TF1::EAddToList) [with Func = TF1*; Double_t = double; Int_t = int]’
test.cpp:11:47:   required from here
/data/disk01/home/riviere/aaaaaa/base/root/build/include/TF1.h:707:102: error: no matching function for call to ‘GetTheRightOp(<unresolved overloaded function type>)’
          using Fnc_t = typename ROOT::Internal::GetFunctorType<decltype(ROOT::Internal::GetTheRightOp(&Func::operator()))>::type;
                                                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
In file included from test.cpp:1:0:
/data/disk01/home/riviere/aaaaaa/base/root/build/include/TF1.h:185:12: note: candidate: template<class T, class F> decltype (opPtr) ROOT::Internal::GetTheRightOp(T (F::*)(const T*, const double*))
       auto GetTheRightOp(T(F::*opPtr)(const T *, const double *)) -> decltype(opPtr)
            ^~~~~~~~~~~~~
/data/disk01/home/riviere/aaaaaa/base/root/build/include/TF1.h:185:12: note:   template argument deduction/substitution failed:
In file included from test.cpp:1:0:
/data/disk01/home/riviere/aaaaaa/base/root/build/include/TF1.h:707:102: note:   types ‘T (F::)(const T*, const double*)’ and ‘Double_t (TF1::)(Double_t, Double_t, Double_t, Double_t) const {aka double (TF1::)(double, double, double, double) const}’ have incompatible cv-qualifiers
          using Fnc_t = typename ROOT::Internal::GetFunctorType<decltype(ROOT::Internal::GetTheRightOp(&Func::operator()))>::type;
                                                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
/data/disk01/home/riviere/aaaaaa/base/root/build/include/TF1.h:707:102: note:   couldn't deduce template parameter ‘T’
In file included from test.cpp:1:0:
/data/disk01/home/riviere/aaaaaa/base/root/build/include/TF1.h:191:12: note: candidate: template<class T, class F> decltype (opPtr) ROOT::Internal::GetTheRightOp(T (F::*)(const T*, const double*) const)
       auto GetTheRightOp(T(F::*opPtr)(const T *, const double *) const) -> decltype(opPtr)
            ^~~~~~~~~~~~~
/data/disk01/home/riviere/aaaaaa/base/root/build/include/TF1.h:191:12: note:   template argument deduction/substitution failed:
In file included from test.cpp:1:0:
/data/disk01/home/riviere/aaaaaa/base/root/build/include/TF1.h:707:102: note:   mismatched types ‘const T*’ and ‘Double_t {aka double}’
          using Fnc_t = typename ROOT::Internal::GetFunctorType<decltype(ROOT::Internal::GetTheRightOp(&Func::operator()))>::type;
                                                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
/data/disk01/home/riviere/aaaaaa/base/root/build/include/TF1.h:707:102: note:   couldn't deduce template parameter ‘T’

We tested with similar results on multiple platforms.
Is there anything wrong with this code, or is it a bug?
It looks similar to https://github.com/root-project/root/pull/1123


ROOT Version: 6.14/06
Platform: macOS, Linux
Compiler: various (on Linux: clang 6, 7, g++ 6, 7, 8; on macOS: Xcode 10.1)
___compilation_error.txt (18.6 KB)

Hi,

what TF1 constructor are you exactly trying to ivoke? You cast to a TF1* which is a bit odd since the only ctor which has a pointer as second argument has the type Double_t(Double_t *, Double_t *) (https://root.cern.ch/doc/master/classTF1.html#aa8905d28455ed7be02019f20b9cc5827).

Cheers,
D

The comments in the original code say

  //This constructor is primarily for the Python wrapper, so that Func1
  //can be created starting from an arbitrary ROOT.TF1 object, casted to void*
  //by using ROOT.AsCObject and the appropriate SWIG typemap

Actually we are not using this python wrapper anymore (replaced by boost::python), so I could simply get rid of the problematic code.
Thanks anyway!

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