mirror of
https://github.com/RYDE-WORK/pybind11.git
synced 2026-01-19 21:23:26 +08:00
This commit adds support for forcing alias type initialization by defining constructors with `py::init_alias<arg1, arg2>()` instead of `py::init<arg1, arg2>()`. Currently py::init<> only results in Alias initialization if the type is extended in python, or the given arguments can't be used to construct the base type, but can be used to construct the alias. py::init_alias<>, in contrast, always invokes the constructor of the alias type. It looks like this was already the intention of `py::detail::init_alias`, which was forward-declared in 86d825f3302701d81414ddd3d38bcd09433076bc, but was apparently never finished: despite the existance of a .def method accepting it, the `detail::init_alias` class isn't actually defined anywhere. This commit completes the feature (or possibly repurposes it), allowing declaration of classes that will always initialize the trampoline which is (as I argued in #397) sometimes useful.
63 lines
1.6 KiB
C++
63 lines
1.6 KiB
C++
/*
|
|
tests/test_alias_initialization.cpp -- test cases and example of different trampoline
|
|
initialization modes
|
|
|
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>, Jason Rhinelander <jason@imaginary.ca>
|
|
|
|
All rights reserved. Use of this source code is governed by a
|
|
BSD-style license that can be found in the LICENSE file.
|
|
*/
|
|
|
|
#include "pybind11_tests.h"
|
|
|
|
test_initializer alias_initialization([](py::module &m) {
|
|
// don't invoke Python dispatch classes by default when instantiating C++ classes that were not
|
|
// extended on the Python side
|
|
struct A {
|
|
virtual ~A() {}
|
|
virtual void f() { py::print("A.f()"); }
|
|
};
|
|
|
|
struct PyA : A {
|
|
PyA() { py::print("PyA.PyA()"); }
|
|
~PyA() { py::print("PyA.~PyA()"); }
|
|
|
|
void f() override {
|
|
py::print("PyA.f()");
|
|
PYBIND11_OVERLOAD(void, A, f);
|
|
}
|
|
};
|
|
|
|
auto call_f = [](A *a) { a->f(); };
|
|
|
|
py::class_<A, PyA>(m, "A")
|
|
.def(py::init<>())
|
|
.def("f", &A::f);
|
|
|
|
m.def("call_f", call_f);
|
|
|
|
|
|
// ... unless we explicitly request it, as in this example:
|
|
struct A2 {
|
|
virtual ~A2() {}
|
|
virtual void f() { py::print("A2.f()"); }
|
|
};
|
|
|
|
struct PyA2 : A2 {
|
|
PyA2() { py::print("PyA2.PyA2()"); }
|
|
~PyA2() { py::print("PyA2.~PyA2()"); }
|
|
void f() override {
|
|
py::print("PyA2.f()");
|
|
PYBIND11_OVERLOAD(void, A2, f);
|
|
}
|
|
};
|
|
|
|
py::class_<A2, PyA2>(m, "A2")
|
|
.def(py::init_alias<>())
|
|
.def("f", &A2::f);
|
|
|
|
m.def("call_f", [](A2 *a2) { a2->f(); });
|
|
|
|
});
|
|
|