From 4697149d19738a674ab59b08492becfcf69a87f8 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 4 Dec 2019 15:03:22 -0800 Subject: [PATCH] Allows users to specialize polymorphic_type_hook with std::enable_if. Currently user specializations of the form template struct polymorphic_type_hook> { ... }; will fail if itype is also polymorphic, because the existing specialization will also be enabled, which leads to 2 equally viable candidates. With this change, user provided specializations have higher priority than the built in specialization for polymorphic types. --- include/pybind11/cast.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index a0b4d1ba..fcfd0a8e 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -835,19 +835,25 @@ NAMESPACE_END(detail) // You may specialize polymorphic_type_hook yourself for types that want to appear // polymorphic to Python but do not use C++ RTTI. (This is a not uncommon pattern // in performance-sensitive applications, used most notably in LLVM.) +// +// polymorphic_type_hook_base allows users to specialize polymorphic_type_hook with +// std::enable_if. User provided specializations will always have higher priority than +// the default implementation and specialization provided in polymorphic_type_hook_base. template -struct polymorphic_type_hook +struct polymorphic_type_hook_base { static const void *get(const itype *src, const std::type_info*&) { return src; } }; template -struct polymorphic_type_hook::value>> +struct polymorphic_type_hook_base::value>> { static const void *get(const itype *src, const std::type_info*& type) { type = src ? &typeid(*src) : nullptr; return dynamic_cast(src); } }; +template +struct polymorphic_type_hook : public polymorphic_type_hook_base {}; NAMESPACE_BEGIN(detail)