@@ -329,8 +329,18 @@ inline void *type_get_slot(handle h, int slot_id) {
329329#endif
330330}
331331
332+ template <typename Visitor> struct def_visitor {
333+ protected:
334+ // Ensure def_visitor<T> can only be derived from, not constructed
335+ // directly
336+ def_visitor () {
337+ static_assert (std::is_base_of_v<def_visitor, Visitor>,
338+ " def_visitor uses CRTP: def_visitor<T> should be "
339+ " a base of T" );
340+ }
341+ };
332342
333- template <typename ... Args> struct init {
343+ template <typename ... Args> struct init : def_visitor<init<Args...>> {
334344 template <typename T, typename ... Ts> friend class class_ ;
335345 NB_INLINE init () {}
336346
@@ -355,7 +365,7 @@ template <typename... Args> struct init {
355365 }
356366};
357367
358- template <typename Arg> struct init_implicit {
368+ template <typename Arg> struct init_implicit : def_visitor<init_implicit<Arg>> {
359369 template <typename T, typename ... Ts> friend class class_ ;
360370 NB_INLINE init_implicit () { }
361371
@@ -455,7 +465,7 @@ template <typename Func, typename Sig = detail::function_signature_t<Func>>
455465struct new_ ;
456466
457467template <typename Func, typename Return, typename ... Args>
458- struct new_ <Func, Return(Args...)> {
468+ struct new_ <Func, Return(Args...)> : def_visitor<new_<Func, Return(Args...)>> {
459469 std::remove_reference_t <Func> func;
460470
461471 new_ (Func &&f) : func((detail::forward_t <Func>) f) {}
@@ -614,21 +624,9 @@ class class_ : public object {
614624 return *this ;
615625 }
616626
617- template <typename ... Args, typename ... Extra>
618- NB_INLINE class_ &def (init<Args...> &&arg, const Extra &... extra) {
619- arg.execute (*this , extra...);
620- return *this ;
621- }
622-
623- template <typename Arg, typename ... Extra>
624- NB_INLINE class_ &def (init_implicit<Arg> &&arg, const Extra &... extra) {
625- arg.execute (*this , extra...);
626- return *this ;
627- }
628-
629- template <typename Func, typename ... Extra>
630- NB_INLINE class_ &def (new_<Func> &&arg, const Extra &... extra) {
631- arg.execute (*this , extra...);
627+ template <typename Visitor, typename ... Extra>
628+ NB_INLINE class_ &def (def_visitor<Visitor> &&arg, const Extra &... extra) {
629+ static_cast <Visitor&&>(arg).execute (*this , extra...);
632630 return *this ;
633631 }
634632
0 commit comments