So as the title (hopefully somewhat) says, I'm trying to achieve a spezialisation of a template class, based on whether or not the template-parameter is derived off of another (templated) class:
// base class, specializations must match this signature
template<typename Object>
class ObjectSupplier
{
public:
static constexpr size_t objectOffset = 1;
static Object& GetClassObject(CallState& state)
{
return *state.GetAttribute<Object>(0);
}
};
// possible specialisation for all "Data"-classes,
// which are actually derived classes using CRTP
template<typename Derived>
class ObjectSupplier<ecs::Data<Derived>>
{
public:
static constexpr size_t objectOffset = 1;
static Derived& GetClassObject(CallState& state)
{
return state.GetEntityAttribute(0)->GetData<Derived>();
}
};
// ... now here's the problem:
// this would work ...
ObjectSupplier<ecs::Data<Transform>>::GetClassObject(state);
// unfornately the actual object is "Transform", which is merely derived
// of "ecs::Data<Transform>" and thus it calls the incorrect overload
ObjectSupplier<Transform>::GetClassObject(state);
The last two lines show the actual problem. I'm using this ObjectSupplier-class as part of my script-binding system, and thus its not possible/feasable to input the required base-class manually:
template<typename Return, typename Class, typename... Args>
void registerBindFunction(ClassFunction<Return, Class, Args...> pFunction, sys::StringView strFilter, std::wstring&& strDefinition)
{
using Supplier = ObjectSupplier<Class>;
using RegistryEntry = BindFunctionRegistryEntry<ClassFunctionBindCommand<Supplier, Class, Return, Args...>>;
registerClassBindEntry<RegistryEntry, Supplier, Return, Args...>(pFunction, false, strFilter, std::move(strDefinition), DEFAULT_INPUT, DEFAULT_OUTPUT);
}
registerBindFunction(&GenericObject::Func, ...);
// needs to access the ObjectSupplier<ecs::Data<Derived>> overload
registerBindFunction(&Transform::GetAbsoluteTransform, ...);
// thats how it used to be before:
registerObjectBindFunction(&GenericObject::Func, ...);
// a few overloads that internally used a "EntityDataSupplier"-class
registerEntityDataBindFunction(&GenericObject::GetAbsoluteTransform, ...);
(well, it were possible, but I want this binding-code to be as simple as humanly possible; which is why I'm trying to not have to manually specify anything other than "I want to bind a function here").
So, thats the gist of it. Any ideas on how to get this to work? I don't want to (again) have to create manual overloads for "registerBindFunctions", which there would have to be at least 5 (and all have a complex signature); but I'm certainly open to different approaches, if what I'm trying to achieve via template specialization isn't possible.
Thanks!
↧