0

I have an issue with C++ templates when using a template function from another class within an exposed template class. The following example should explain my issue:

Source files:

b.h

#include <pybind11/pybind11.h>

namespace py = pybind11;

namespace test {

template <typename T>
class B {
    public:
    B();
    T getSomething(T) const;
};

}

void bind_b(py::module &m);

b.ccp

#include <pybind11/pybind11.h>
#include "b.h"
#include "c.h"

namespace py = pybind11;

template <typename T>
test::B<T>::B(){}

template <typename T>
T test::B<T>::getSomething(T input) const{
  return test::doSomething(input);
}

void bind_b(py::module &m) {
    py::class_<test::B<int>>(m, "B")
      .def(py::init())
      .def("getSomething", &test::B<int>::getSomething);
}

c.h

namespace test {

template <typename T>
T doSomething(T input);

}

c.cpp

#include "c.h"

template <typename T>
T test::doSomething(T input) {
  return input;
}

Binding File:

module.cpp

#include <pybind11/pybind11.h>
#include "b.h"

namespace py = pybind11;

PYBIND11_MODULE(m, handle) {
  handle.doc() = "Example Module";
  bind_b(handle);
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.4...3.18)
project(example)

add_subdirectory(pybind11)
pybind11_add_module(m module.cpp b.cpp c.cpp)

When I now try to import the module after compiling I get an Import Error /home/runner/example/build/m.cpython-38-x86_64-linux-gnu.so: undefined symbol: _ZN4test11doSomethingIiEET_S1_, which makes sense because doSomething is not declared for int inputs. The declared template function does not seem to be sufficient here. How can make templates work in this case without having to implement each function for every file type?

chicom
  • 35
  • 4

0 Answers0