Problems compiling templates

Hi,

I need to compile a quite simple template inheriting from TObject to be able to load it afterwards in ROOT (for PROOF). I cannot use ACLIC since PROOF doesn’t like it (I have problems when uploading and enabling the package in the slaves). I am using root version 5.27.06 for this tests on a SLC5 linux box.

The header file looks like:

#ifndef TPROOFVECTOR_H
#define TPROOFVECTOR_H 1

#include "TNamed.h"
#include "TCollection.h"

#include <vector>
#include <algorithm>


//Forward declaration
template <typename T> class TProofVector;

//Some typedefs for already defined types
typedef TProofVector<unsigned int> TProofVectorUI;
typedef TProofVector<int>          TProofVectorI;
typedef TProofVector<long int>     TProofVectorLI;
typedef TProofVector<float>	    TProofVectorF;
typedef TProofVector<double>       TProofVectorD;

template <typename T>
class TProofVector:public TNamed, public std::vector<T> {

 public:
  TProofVector(const char* title = "", const char* name = ""):
    TNamed(title, name) {}
  ~TProofVector() {}

  // Used by Proof in the merging
  Int_t Merge(TCollection *li);

  // Sorts this collection according to the from smaller to bigger according
  // to the result of the < operator
  void Sort() { std::sort(this->begin(), this->end());}

  //True if the collection has an element which is equal to the argument
  bool Contains(const T& e) const;

  //Returns the index of the first element found which is equal to the 
  //argument. If no equal element is found it returns size()
  unsigned int FindIndex(const T& e) const;

  //std::vector<T>::const_iterator begin() const {return fCollection.begin();}
  //std::vector<T>::const_iterator end() const {return fCollection.end();}

 protected:

  ClassDef(TProofVector,1);
};

template <typename T>
Int_t TProofVector<T>::Merge(TCollection *li) {
  if (!li) 
    return 0;
  if (li->IsEmpty()) 
    return (Int_t) li->GetEntries();

  TIter next(li);
  TProofVector* n = (TProofVector*)next();
  while(n) {
    for (unsigned int i = 0; i < n->size(); i++)
      push_back(n->at(i));
    n = (TProofVector*)next();
  }

  return 0;
}
 

template <typename T>
bool TProofVector<T>::Contains(const T& e) const {
  for (unsigned int i = 0; i < this->size(); i++)
    if (this->at(i) == e)
      return true;
  //  if (std::find(this->begin(), this->end(), e) == this->end())
  //  return true;
  return false;
}

template <typename T>
unsigned int TProofVector<T>::FindIndex(const T& e) const {
  for (unsigned int i = 0; i < this->size(); i++)
    if (this->at(i) == e)
      return i;
  return this->size();
}

#endif

And the implementation file is pretty simple:

#include "TProofVector.h"

#if !defined(__CINT__)
templateClassImp(TProofVector);
#endif

I expected that,somehow, rootcint was able to generate the dictionaries automatically (like ACLIC does), but this seems not to be the case, so I added a Linkdef.h file:

#pragma link C++ class TProofVector<unsigned int>;
#pragma link C++ class std::vector<unsigned int>;
#pragma link C++ class std::vector<unsigned int>::iterator;
#pragma link C++ operators std::vector<unsigned int>::iterator;
#pragma link C++ class std::vector<unsigned int>::const_iterator;
#pragma link C++ operators std::vector<unsigned int>::const_iterator;
#pragma link C++ class std::vector<unsigned int>::reverse_iterator;
#pragma link C++ operators std::vector<unsigned int>::reverse_iterator;


#pragma link C++ class TProofVector<int>;
#pragma link C++ class std::vector<int>;
#pragma link C++ class std::vector<int>::iterator;
#pragma link C++ operators std::vector<int>::iterator;
#pragma link C++ class std::vector<int>::const_iterator;
#pragma link C++ operators std::vector<int>::const_iterator;
#pragma link C++ class std::vector<int>::reverse_iterator;
#pragma link C++ operators std::vector<int>::reverse_iterator;

#pragma link C++ class TProofVector<long int>;
#pragma link C++ class std::vector<long int>;
#pragma link C++ class std::vector<long int>::iterator;
#pragma link C++ operators std::vector<long int>::iterator;
#pragma link C++ class std::vector<long int>::const_iterator;
#pragma link C++ operators std::vector<long int>::const_iterator;
#pragma link C++ class std::vector<long int>::reverse_iterator;
#pragma link C++ operators std::vector<long int>::reverse_iterator;

#pragma link C++ class TProofVector<float>;
#pragma link C++ class std::vector<float>;
#pragma link C++ class std::vector<float>::iterator;
#pragma link C++ operators std::vector<float>::iterator;
#pragma link C++ class std::vector<float>::const_iterator;
#pragma link C++ operators std::vector<float>::const_iterator;
#pragma link C++ class std::vector<float>::reverse_iterator;
#pragma link C++ operators std::vector<float>::reverse_iterator;

#pragma link C++ class TProofVector<double>;
#pragma link C++ class std::vector<double>;
#pragma link C++ class std::vector<double>::iterator;
#pragma link C++ operators std::vector<double>::iterator;
#pragma link C++ class std::vector<double>::const_iterator;
#pragma link C++ operators std::vector<double>::const_iterator;
#pragma link C++ class std::vector<double>::reverse_iterator;
#pragma link C++ operators std::vector<double>::reverse_iterator;

The result of rootcint over this files is:

$ rootcint -f TProofVectorCint.cxx -c -I/nfs/fanae/root_releases/root-5.27.06/include TProofVector.h Linkdef.h
Note: Link requested for already precompiled class vector<long,allocator<long> > (ignore this message) :0:
Note: Link requested for already precompiled class vector<long,allocator<long> >::iterator (ignore this message) :0:
Note: Link requested for already precompiled class reverse_iterator<vector<long,allocator<long> >::iterator> (ignore this message) :0:
Note: Link requested for already precompiled class vector<unsigned int,allocator<unsigned int> > (ignore this message) :0:
Note: Link requested for already precompiled class vector<unsigned int,allocator<unsigned int> >::iterator (ignore this message) :0:
Note: Link requested for already precompiled class reverse_iterator<vector<unsigned int,allocator<unsigned int> >::iterator> (ignore this message) :0:
Note: Link requested for already precompiled class vector<float,allocator<float> > (ignore this message) :0:
Note: Link requested for already precompiled class vector<float,allocator<float> >::iterator (ignore this message) :0:
Note: Link requested for already precompiled class reverse_iterator<vector<float,allocator<float> >::iterator> (ignore this message) :0:
Note: Link requested for already precompiled class vector<double,allocator<double> > (ignore this message) :0:
Note: Link requested for already precompiled class vector<double,allocator<double> >::iterator (ignore this message) :0:
Note: Link requested for already precompiled class reverse_iterator<vector<double,allocator<double> >::iterator> (ignore this message) :0:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:37:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:38:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:43:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:44:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:45:
Error: class,struct,union or type unsignedint not defined  prec_stl/vector:51:
Error: Function unsignedint() is not defined in current scope  prec_stl/vector:444:
Error: Function unsignedint() is not defined in current scope  prec_stl/vector:444:
*** Interpreter error recovered ***
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:37:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:38:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:43:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:44:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:45:
Error: class,struct,union or type unsignedint not defined  prec_stl/vector:51:
Error: Function unsignedint() is not defined in current scope  prec_stl/vector:444:
Error: Function unsignedint() is not defined in current scope  prec_stl/vector:444:
*** Interpreter error recovered ***
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:37:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:38:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:43:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:44:
Error: class,struct,union or type unsignedint not defined  prec_stl/memory:45:
Error: class,struct,union or type unsignedint not defined  prec_stl/vector:51:
Error: Function unsignedint() is not defined in current scope  prec_stl/vector:444:
Error: Function unsignedint() is not defined in current scope  prec_stl/vector:444:
*** Interpreter error recovered ***

A hint will be very much appreciated. Thanks!

You do not need to create a dictionary for the vector of most basic types. They are already included by default.
Simply remove the pragma statement for all cases where ROOT find a duplicate entry.

Rene

Hi,

and the error regarding the “unsigned int” cases was fixed in v5.27.06a and the trunk.

Cheers, Axel.