Dictionary linkdef template fuction

Hi all.

I’m having trouble figuring out how to get my template function properly defined in my dictionary.

basically, I have the following

class KPtaProcessor {
public:
  KPtaProcessor(void);
  virtual ~KPtaProcessor(void);

  //all derived classes must over-ride this method
  virtual bool RunProcess(void) = 0;

  template <class T> void SetInputPulse(const std::vector<T> &aPulse);
  template <class T> void SetInputPulse(const T* aPulse, unsigned int size);

  virtual void SetInputPulse(KPtaProcessor *pta);
  virtual void SetInputPulse(const char* aFile);
  virtual void SetInputPulse(double *apulse); //for memory-savy users...
};

template <class T> void KPtaProcessor::SetInputPulse(const T* aPulse, unsigned int size)
{
 //... do stuff
}


template <class T> void KPtaProcessor::SetInputPulse(const std::vector<T> &aPulse)
{
 //... do stuff
}

My linkdef file looks like this:

#include <vector>
#include "KPtaProcessor.h"
//using namespace std;

#ifdef __CINT__ 
#pragma link off all globals; 
#pragma link off all classes; 
#pragma link off all functions; 
#pragma link C++ nestedclasses;
#pragma link C++ nestedtypedef;

// #pragma link C++ class std::vector<double>;
// #pragma link C++ class std::vector<float>;
// #pragma link C++ class std::vector<int>;
// #pragma link C++ class std::vector<short>;
#pragma link C++ class KPtaProcessor+;
#pragma link C++ function <double>KPtaProcessor::SetInputPulse(std::vector<double>&);
#pragma link C++ function <float>KPtaProcessor::SetInputPulse(std::vector<float>& );
#pragma link C++ function <int>KPtaProcessor::SetInputPulse(std::vector<int>& );
#pragma link C++ function <short>KPtaProcessor::SetInputPulse(std::vector<short>& );
#pragma link C++ function KPtaProcessor::SetInputPulse(double*, unsigned int );
#pragma link C++ function KPtaProcessor::SetInputPulse(float*, unsigned int );
#pragma link C++ function KPtaProcessor::SetInputPulse(int*, unsigned int );
#pragma link C++ function KPtaProcessor::SetInputPulse(short*, unsigned int );

#pragma link C++ class KBaselineRemoval+;
#endif 

where the “KBaselineRemoval” is a subclass of KPtaProcessor.

Building doesn’t complain. But then I can’t pass in a vector from the ROOT CINT. It seems that I’m doing the template for the (double*, int) functions correctly.

Here is my ROOT session:

[code]
11:55am adam:root
root [0] gSystem->Load(“libkpta”)
(int)0
root [1] vector apulse;
root [2] for(int i = 0; i< 1000; ++i)apulse.push_back(i);
root [3] KBaselineRemoval b
root [4] b.SetInputPulse(apulse)
Error: Can’t call KBaselineRemoval::SetInputPulse(apulse) in current scope (tmpfile):1:
Possible candidates are…
(in KBaselineRemoval)
(in KPtaProcessor)
/Users/adam/softwareDev/kdata/lib/libkpta.so -1:-1 0 public: virtual void KPtaProcessor::SetInputPulse(KPtaProcessor* pta);
/Users/adam/softwareDev/kdata/lib/libkpta.so -1:-1 0 public: virtual void KPtaProcessor::SetInputPulse(const char* aFile);
/Users/adam/softwareDev/kdata/lib/libkpta.so -1:-1 0 public: virtual void KPtaProcessor::SetInputPulse(double* aPulse);
/Users/adam/softwareDev/kdata/lib/libkpta.so -1:-1 0 public: void KPtaProcessor::SetInputPulse(const double* aPulse,unsigned int size);
/Users/adam/softwareDev/kdata/lib/libkpta.so -1:-1 0 public: void KPtaProcessor::SetInputPulse(const float* aPulse,unsigned int size);
/Users/adam/softwareDev/kdata/lib/libkpta.so -1:-1 0 public: void KPtaProcessor::SetInputPulse(const int* aPulse,unsigned int size);
/Users/adam/softwareDev/kdata/lib/libkpta.so -1:-1 0 public: void KPtaProcessor::SetInputPulse(const short* aPulse,unsigned int size);
*** Interpreter error recovered ***
root [5] b.SetInputPulse(&apulse[0], apulse.size())

root [10] apulse[1]
(vector<double,allocator >::reference)1.00000000000000000e+00
root [11] apulse[2]
(vector<double,allocator >::reference)2.00000000000000000e+00

root [14] b.GetInputPulse()[1]
(const double)1.00000000000000000e+00
root [15] b.GetInputPulse()[2]
(const double)2.00000000000000000e+00
[\code]

thanks very much for your help.

Adam

Instead of: #pragma link C++ function <double>KPtaProcessor::SetInputPulse(std::vector<double>&); #pragma link C++ function <float>KPtaProcessor::SetInputPulse(std::vector<float>& ); #pragma link C++ function <int>KPtaProcessor::SetInputPulse(std::vector<int>& ); #pragma link C++ function <short>KPtaProcessor::SetInputPulse(std::vector<short>& ); #pragma link C++ function KPtaProcessor::SetInputPulse(double*, unsigned int ); #pragma link C++ function KPtaProcessor::SetInputPulse(float*, unsigned int ); #pragma link C++ function KPtaProcessor::SetInputPulse(int*, unsigned int ); #pragma link C++ function KPtaProcessor::SetInputPulse(short*, unsigned int ); try: #pragma link C++ function KPtaProcessor::SetInputPulse<double>; #pragma link C++ function KPtaProcessor::SetInputPulse<float>; #pragma link C++ function KPtaProcessor::SetInputPulse<int>; #pragma link C++ function KPtaProcessor::SetInputPulse<short>;

oh man… that worked.

i could have sworn that i already tried this one. I thought that I tried every possible iteration of argument…

thanks a lot!
Adam

Hi again… I have another problem that is related to my original question.

I have a template function that I want to return a map<string, KResult>, but I can’t get the dictionary generated properly.

My function looks like this:

class A {
template <class T> std::map<std::string, KResult> TestFunc(const std::vector<T> &aPulse, unsigned int i, const char* name);
};
template <class T> std::map<std::string, KResult> A::TestFunc(const std::vector<T> &aPulse, unsigned int i, const char* name){
...my code
}

And my lindef line looks like:

#pragma link C++ class KResult+;

#pragma link C++ class std::map<std::string, KResult>+;
#pragma link C++ class std::pair<std::string, KResult>+;
#pragma link C++ class std::map<std::string, KResult>::*;
#pragma link C++ operators std::map<std::string, KResult>::iterator; 
#pragma link C++ operators std::map<std::string, KResult>::const_iterator;
#pragma link C++ operators std::map<std::string, KResult>::reverse_iterator;

#pragma link C++ class A+;
#pragma link C++ function A::TestFunc<double>;

The rootcint error is:

However, this DOES work when I return ‘void’, ‘double’, ‘KResult’, or ‘T’ from template the template function. It does NOT work when I try to return a map<string, double>, map<string, T>…

thanks in advance for your help.
adam

Try to hide the implementation from CINT (and “rootcint”, too) … #if !defined(__CINT__) template <class T> std::map<std::string, KResult> A::TestFunc(const std::vector<T> &aPulse, unsigned int i, const char* name){ ...my code } #endif /* !defined(__CINT__) */

Thanks - that seemed to work.

Adam