1

I'm trying to write a cython wrapper for some templated C++ code. I'm pretty familiar with wrapping something written like Bar. i.e. (with details removed)

 ctypedef enum enum_t "enum_t":
    OPT1 "OPT1",
    OPT2 "OPT2",
    OPT3 "OPT3"

 cdef cppclass Bar[A, B, T, ALLOCATOR=*] 

 new Bar[OPT1, OPT2, float]

But I'm having trouble understanding what the practice is for wrapping instances of something like Bar<OPT1, OPT2, T> or Bar<OPT3, OPT4, T> defined below. Could someone point me in the right direction? What I've tried has given me an "OPT1 is ambiguous" error at compilation.

typedef enum
{
  OPT1, 
  OPT2,
  OPT3,
} enum_t;

template<class T, class Allocator = std::allocator<T> >
class BarBase : public Foo<T, Allocator>, public mpi::MPIObject
{
  //Generic class methods and variables
}

template<enum_t A, enum_t B, class T, class Allocator = std::allocator<T> >
    class Bar : public BarBase<T, Allocator>
    {
      public:
      private:
    };

template<typename T>
class Bar<OPT1, OPT2, T> : public BarBase<T>
    {
      //Specific class methods here
    }

template<typename T>
class Bar<OPT3, OPT4, T> : public BarBase<T>
    {
      //Specific class methods here
    }

1 Answers1

2

Cython doesn't really support non-type template parameters. In previous questions when using int template parameters I've recommended using "fake" classes with names signed on generate the correct C++ code. The same principle applies here:

cdef extern from "X.hpp":        
    cdef cppclass OPT1:
        pass
    cdef cppclass OPT2:
        pass

    cdef cppclass Bar[A, B, T]:
        pass

def f():
    cdef Bar[OPT1,OPT2,float]* p = new Bar[OPT1,OPT2,float]()

I've simply told Cython that OPT1 and OPT2 are classes rather than enum values and this tricks Cython into generating the correct code.

DavidW
  • 29,336
  • 6
  • 55
  • 86