Reputation: 998
I have class TLuaClassTemplate<T: TControl, constructor> = class
and trying to use it's method class procedure RegisterClass(L: Plua_State; p: TPrintProc; container: TComponent; vm: TLuaVm); static;
with TControlClass references stored in TDictionary
TClassNameToComponentDict = TDictionary<string, TControlClass>;
TClassNameToComponentPair = TPair<string, TControlClass>;
...
ClassNameToComponent := TClassNameToComponentDict.Create;
ClassNameToComponent.Add('TButton', TButton);
ClassNameToComponent.Add('TPanel', TPanel);
ClassNameToComponent.Add('TEdit', TEdit);
But I have problem on attempt to use it
enum: TClassNameToComponentPair;
ctx: TRttiContext;
cls: TControlClass;
begin
for enum in vm.ClassNameToComponent do begin
//TLuaClassTemplate<enum.Value>.RegisterClass(vm.LS, PrintGlobal, container, vm);
cls := TControlClass((ctx.FindType(enum.Key) as TRttiInstanceType).MetaClassType);
TLuaClassTemplate<cls>.RegisterClass(vm.LS, PrintGlobal, container, vm);
end;
I've tried both current visible (found by searching) and commented options. But error is Undeclared identifier: 'TLuaClassTemplate'
while TLuaClassTemplate<TButton>.RegisterClass(vm.LS, PrintGlobal, container, vm);
works.
How can I use TControlClass as generic parameter here?
Upvotes: 4
Views: 276
Reputation: 612983
The issue that you have is that instantiation of a generic requires that the type arguments are known at compile time. In your code cls
is not known at compile time, it is only determined at runtime. And that means that TLuaClassTemplate<cls>
is an invalid instantiation of the generic.
The bottom line here is that generics give you parameterisation of your code, but the parameters must be supplied at compile time. Since you don't know the parameters until runtime, you cannot solve your problem using generics.
Well, I say, cannot, but you could use RTTI to call your generic method. For that to work you'd need to ensure that each possible instantiated type was included in the executable's list of types. But doing all that would really defeat the purposes of generics! It's going to be much easier to use standard runtime arguments rather than compile time generic arguments.
Upvotes: 4