mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 05:05:11 +00:00
Document how to bind templates (#3665)
This commit is contained in:
parent
ec81e8e778
commit
177928840e
@ -1161,6 +1161,58 @@ error:
|
|||||||
|
|
||||||
.. versionadded:: 2.6
|
.. versionadded:: 2.6
|
||||||
|
|
||||||
|
Binding classes with template parameters
|
||||||
|
========================================
|
||||||
|
|
||||||
|
pybind11 can also wrap classes that have template parameters. Consider these classes:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
struct Cat {};
|
||||||
|
struct Dog {};
|
||||||
|
|
||||||
|
template <typename PetType>
|
||||||
|
struct Cage {
|
||||||
|
Cage(PetType& pet);
|
||||||
|
PetType& get();
|
||||||
|
};
|
||||||
|
|
||||||
|
C++ templates may only be instantiated at compile time, so pybind11 can only
|
||||||
|
wrap instantiated templated classes. You cannot wrap a non-instantiated template:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
// BROKEN (this will not compile)
|
||||||
|
py::class_<Cage>(m, "Cage");
|
||||||
|
.def("get", &Cage::get);
|
||||||
|
|
||||||
|
You must explicitly specify each template/type combination that you want to
|
||||||
|
wrap separately.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
// ok
|
||||||
|
py::class_<Cage<Cat>>(m, "CatCage")
|
||||||
|
.def("get", &Cage<Cat>::get);
|
||||||
|
|
||||||
|
// ok
|
||||||
|
py::class_<Cage<Dog>>(m, "DogCage")
|
||||||
|
.def("get", &Cage<Dog>::get);
|
||||||
|
|
||||||
|
If your class methods have template parameters you can wrap those as well,
|
||||||
|
but once again each instantiation must be explicitly specified:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
typename <typename T>
|
||||||
|
struct MyClass {
|
||||||
|
template <typename V>
|
||||||
|
T fn(V v);
|
||||||
|
};
|
||||||
|
|
||||||
|
py::class<MyClass<int>>(m, "MyClassT")
|
||||||
|
.def("fn", &MyClass<int>::fn<std::string>);
|
||||||
|
|
||||||
Custom automatic downcasters
|
Custom automatic downcasters
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
@ -578,3 +578,38 @@ prefers earlier-defined overloads to later-defined ones.
|
|||||||
.. versionadded:: 2.6
|
.. versionadded:: 2.6
|
||||||
|
|
||||||
The ``py::prepend()`` tag.
|
The ``py::prepend()`` tag.
|
||||||
|
|
||||||
|
Binding functions with template parameters
|
||||||
|
==========================================
|
||||||
|
|
||||||
|
You can bind functions that have template parameters. Here's a function:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void set(T t);
|
||||||
|
|
||||||
|
C++ templates cannot be instantiated at runtime, so you cannot bind the
|
||||||
|
non-instantiated function:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
// BROKEN (this will not compile)
|
||||||
|
m.def("set", &set);
|
||||||
|
|
||||||
|
You must bind each instantiated function template separately. You may bind
|
||||||
|
each instantiation with the same name, which will be treated the same as
|
||||||
|
an overloaded function:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
m.def("set", &set<int>);
|
||||||
|
m.def("set", &set<std::string>);
|
||||||
|
|
||||||
|
Sometimes it's more clear to bind them with separate names, which is also
|
||||||
|
an option:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
m.def("setInt", &set<int>);
|
||||||
|
m.def("setString", &set<std::string>);
|
||||||
|
Loading…
Reference in New Issue
Block a user