How to create an object of a c++ template class in PyROOT?

Hi,
I am trying to use template class in c++ which I would like to use from python. A simple example here:

#include <iostream>
using namespace std;
template <class T>
class mypair {
    T a, b;
  public:
    mypair (T first, T second);
};
template <class T>
mypair<T>::mypair(T first, T second){a=first; b=second;}

I can create an object for this class in c++ as:
mypair <int>myobject (100, 75);

My question is how to create myobject like instance in python?

Normally I create an object in python like below: (supposing above code is saved in cppcode.cc file)

import ROOT
ROOT.gROOT.ProcessLineSync(".L cppcode.cc")
myobject = ROOT.mypair(100,30)

But this seems to be an incorrect way to create an object for template class. Please enlighten me with the correct way.


ROOT Version: 6.18.04
Platform: Ubuntu
Compiler: g++7.5.0, python2.7.5


Hi,
in general:

~ python
Python 3.8.3 (default, May 17 2020, 18:15:42) 
[GCC 10.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ROOT
>>> ROOT.gInterpreter.Declare("""template <typename T> T foo(T t) { return t*2; }""")
True
>>> ROOT.foo(4)
8
>>> ROOT.foo(4.)
8.0
>>> ROOT.foo("x")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Template method resolution failed:
  none of the 2 overloaded methods succeeded. Full details:
  int ::foo(int t) =>
    TypeError: could not convert argument 1 (int/long conversion expects an integer object)
  double ::foo(double t) =>
    TypeError: could not convert argument 1 (must be real number, not str)
  Failed to instantiate "foo(std::string)"

For your usecase:

~ python
Python 3.8.3 (default, May 17 2020, 18:15:42) 
[GCC 10.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ROOT
>>> ROOT.gInterpreter.Declare("""template <class T>
... class mypair {
...     T a, b;
...   public:
...     mypair (T first, T second);
... };
... template <class T>
... mypair<T>::mypair(T first, T second){a=first; b=second;}
... """)
True
>>> ROOT.mypair('int')(1,2)
<cppyy.gbl.mypair<int> object at 0x560cb99f2150>

or, if you have the template in header foo.h:

>>> import ROOT
>>> ROOT.gInterpreter.Declare('#include "foo.h"')
True
>>> ROOT.mypair
<cppyy.Template 'mypair' object at 0x7f01745db160>

Cheers,
Enrico

1 Like

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