Problem defining vector of pair of classes

Hello everyone,

I’m trying to import some c++ compiled class consisting of vector of pair of custom classes.
While this work in ROOT I can’t get it to work in pyROOT.

Here are more details :

My source :

[code]#include
#include

class AA {
public:
int a;
};
class BB {
public:
int a;
};

typedef std::vector< AA > vAA;
typedef std::pair<AA ,BB> pAB;
typedef std::vector< std::pair<AA ,BB> > vAB;

#ifdef MAKECINT
#pragma link C++ class vAA;
#pragma link C++ class pAB;
#pragma link C++ class vAB;
#endif
[/code]

I compile it with Aclic. Now here is my pyRoot sequence :

>>> gROOT.ProcessLine(".L vectorpair.C+")
0L
>>> pab = pAB()
>>> pab.first
<ROOT.AA object at 0x941d208>
>>> vab = vAB()
>>> vab
<ROOT.vector<pair<AA,BB> > object at 0x(nil)>
>>> vab.push_back(p)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'vAB' object has no attribute 'push_back'
>>> dir(vab)
['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__']
>>> dir(pab)
['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', '_pair<AA,BB>____assign__', 'first', 'pair', 'second']
>>> 

The exact equivalent in CINT works as expected (i.e vab has all the vector method recognized).

I’m working with ROOT 5.22.

Am I missing something specific to PyRoot ?

Cheers,

P.A.

Hi,

it’s a problem with looking op the class through root/meta, b/c of std::. This is something that has been coming and going (it’s not a problem with HEAD, as it is likely fixed with this: http://savannah.cern.ch/bugs/?46572). Dropping ‘std::’ from the macro for at least the std::pair argument of the vector template does the trick, as a possible workaround.

With ‘std::’, CINT session: root [0] .L vectorpair.C+ root [1] TClass::GetClass( "std::vector< std::pair< AA, BB > >" )->GetListOfAllPublicMethods()->GetSize() (const Int_t)0 root [2]

Without ‘std::’, CINT session: root [0] .L vectorpair.C+ root [1] TClass::GetClass( "std::vector< std::pair< AA, BB > >" )->GetListOfAllPublicMethods()->GetSize() (const Int_t)30 root [2]

Cheers,
Wim

Hi Wim,

I guess you forgot to remove ‘std::’ in your 2nd example ?

Anyway, it indeed works :

instead of

did the trick.

Thanks a lot !

P.A.

Hi,

No, I didn’t. :slight_smile: There’s a lot of history here (historically, CINT dropped all ‘std::’), and the ROOT/meta string parsing (and therefore the GetClass() call) will work both with and without the ‘std::’ once it has been dropped in the .C file.

Cheers,
Wim