Home | News | Documentation | Download

Inheriting Constructors

Hello, I am trying to make a derived class which inherits everything from ROOT::Math::Interpolator but overloads the Eval method to take Eval(Double_t *, Double_t *) so that I can use it to initialize a TF1. It seems like it should be straightforward, here is my code:

#include "TNtuple.h"
#include "Math/Interpolator.h"
#include <iostream>
#include "TString.h"

class MyInterpolator : public ROOT::Math::Interpolator
{
public:
  using ROOT::Math::Interpolator::Interpolator;
  using ROOT::Math::Interpolator::Eval;
  Double_t Eval (Double_t * x, Double_t * p) const
  {
    return this->ROOT::Math::Interpolator::Eval(*x);
  }
};

MyInterpolator * t2xer(Int_t j)
{
  TNtuple tn("CalibData","CalibData","w:a:x:t:y");
  tn.ReadFile("virtual_garfield/xt-relations_trimmed.dat","",',');
  const Int_t i = j+1;

  Int_t ni = tn.Draw("x:t",TString::Format("w==%i && x >= 0",i),"goff");
  MyInterpolator * inter = new MyInterpolator(ni,ROOT::Math::Interpolation::kAKIMA);
  inter->SetData(ni,tn.GetV2(),tn.GetV1());

  return inter;

}

This worked fine when I used regular ROOT::Math::Interpolator instead of MyInterpolator, but with the derived class, I couldn’t get the constructor to be inherited. I thought it should work fine according to this document: http://en.cppreference.com/w/cpp/language/using_declaration

But instead I get compilation errors.

root [0] .L t2x.C++ Info in <TUnixSystem::ACLiC>: creating shared library /Users/jfcaron/Projects/Proto2BeamTest2/./t2x_C.so In file included from /Users/jfcaron/Projects/Proto2BeamTest2/t2x_C_ACLiC_dict.cxx:17: In file included from /Users/jfcaron/Projects/Proto2BeamTest2/t2x_C_ACLiC_dict.h:34: /Users/jfcaron/Projects/Proto2BeamTest2/./t2x.C:15:35: error: using declaration can not refer to a constructor using ROOT::Math::Interpolator::Interpolator; ~~~~~~~~~~~~~~~~~~~~~~~~~~^ /Users/jfcaron/Projects/Proto2BeamTest2/./t2x.C:17:43: warning: unused parameter 'p' [-Wunused-parameter] Double_t Eval (Double_t * x, Double_t * p) const ^ /Users/jfcaron/Projects/Proto2BeamTest2/./t2x.C:45:32: error: no matching constructor for initialization of 'MyInterpolator' MyInterpolator * inter = new MyInterpolator(ni,ROOT::Math::Interpolation::kAKIMA); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /Users/jfcaron/Projects/Proto2BeamTest2/./t2x.C:12:7: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 2 were provided class MyInterpolator : public ROOT::Math::Interpolator ^ /Users/jfcaron/Projects/Proto2BeamTest2/./t2x.C:12:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided 1 warning and 2 errors generated. clang: error: no such file or directory: '/Users/jfcaron/Projects/Proto2BeamTest2/t2x_C_ACLiC_dict.o' Error in <ACLiC>: Compilation failed!

I recognize that the cppreference link says this only works in C++11, but since I am compiling the code, I thought that C++11 code should work. In any case, can anyone suggest a workaround, either to enable C++11, or inherit the constructor properly?

Thanks,
Jean-François

I got help on IRC which resolved my problem. You can explicitly define a constructor for the derived class which calls the base class constructor:

class MyInterpolator : public ROOT::Math::Interpolator
{
public:
  MyInterpolator(unsigned int ndata, 
		 ROOT::Math::Interpolation::Type type) : ROOT::Math::Interpolator(ndata, type) {};
  
  using ROOT::Math::Interpolator::Eval;
  Double_t Eval (Double_t * x, Double_t * p) const
  {
    return this->ROOT::Math::Interpolator::Eval(*x);
  }
};

I don’t know why the “{ }” is there, but it’s actually supposed to be empty. I couldn’t figure out how to make it compile with default arguments present, but it works for me now.

Jean-François