Skip to content

Commit b2d19d7

Browse files
committed
Fix assertion failure for unions (pybind#1685)
In def_readonly and def_readwrite, there is an assertion that the member comes from the class or a base class: static_assert(std::is_base_of<C, type>::value, "..."); However, if C and type are the same type, is_base_of will still only be true if they are the same _non-union_ type. This means we can't define accessors for the members of a union type because of this assertion. Update the assertion to test std::is_same<C, type>::value || std::is_base_of<C, type>::value which will allow union types, or members of base classes.
1 parent 25abf7e commit b2d19d7

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

include/pybind11/pybind11.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,7 +1176,7 @@ class class_ : public detail::generic_type {
11761176

11771177
template <typename C, typename D, typename... Extra>
11781178
class_ &def_readwrite(const char *name, D C::*pm, const Extra&... extra) {
1179-
static_assert(std::is_base_of<C, type>::value, "def_readwrite() requires a class member (or base class member)");
1179+
static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value, "def_readwrite() requires a class member (or base class member)");
11801180
cpp_function fget([pm](const type &c) -> const D &{ return c.*pm; }, is_method(*this)),
11811181
fset([pm](type &c, const D &value) { c.*pm = value; }, is_method(*this));
11821182
def_property(name, fget, fset, return_value_policy::reference_internal, extra...);
@@ -1185,7 +1185,7 @@ class class_ : public detail::generic_type {
11851185

11861186
template <typename C, typename D, typename... Extra>
11871187
class_ &def_readonly(const char *name, const D C::*pm, const Extra& ...extra) {
1188-
static_assert(std::is_base_of<C, type>::value, "def_readonly() requires a class member (or base class member)");
1188+
static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value, "def_readonly() requires a class member (or base class member)");
11891189
cpp_function fget([pm](const type &c) -> const D &{ return c.*pm; }, is_method(*this));
11901190
def_property_readonly(name, fget, return_value_policy::reference_internal, extra...);
11911191
return *this;

0 commit comments

Comments
 (0)