Virtual templates members

Nicolas Sicard dransic at gmail.com
Thu Aug 8 10:32:55 PDT 2013


On Thursday, 8 August 2013 at 16:58:37 UTC, JS wrote:
> On Thursday, 8 August 2013 at 07:21:19 UTC, Nicolas Sicard 
> wrote:
>> On Thursday, 8 August 2013 at 01:48:49 UTC, JS wrote:
>>> The following code is used to reduce dependence on new and 
>>> the GC. iNew is used as the replacement.
>>>
>>> The problem is, where ever New is used, it requires typing 
>>> the type twice.
>>>
>>> e.g.,
>>>
>>> A.New!A(...)
>>>
>>> instead of A.New(...)
>>>
>>> Is there any way to solve this issue?
>>>
>>> (iNew is suppose to provide the contract to implement a "new" 
>>> like method that will allocate the class. Note there is no 
>>> virtual function so no overhead)
>>>
>>>
>>> import std.stdio, std.conv;
>>>
>>> enum eNew
>>> {
>>> 	Default = 0,
>>> }
>>>
>>> interface iNew
>>> {
>>>
>>> 	final static T New(T, A...)(A args)
>>> 	{
>>> 		eNew type = eNew.Default;
>>> 		static if (A.length == 0 || !is(typeof(args[0]) == eNew))
>>> 			alias nargs = args;
>>> 		else
>>> 		{
>>> 			type = cast(eNew)args[0];
>>> 			alias nargs = args[1..$];
>>> 		}
>>>
>>> 		writeln(">> ",  __traits(classInstanceSize, T));
>>>
>>> 		switch (type)
>>> 		{	
>>> 			default: return new T(nargs);
>>> 		}
>>> 		
>>> 		return new T(nargs);
>>> 	}
>>> }
>>>
>>> class A : iNew
>>> {
>>> 	int t;
>>> }
>>>
>>> class B : A
>>> {
>>> 	int q;
>>>   double d;
>>> }
>>>
>>> void main()
>>> {
>>> 	A a = A.New!A();
>>> 	B b = B.New!B();
>>> 	readln();
>>> }
>>
>> Why not make it a mixin template?
>> ---
>> import std.stdio, std.conv;
>>
>> enum eNew
>> {
>> 	Default = 0,
>> }
>>
>> mixin template iNew(T)
>> {
>> 	final static T New(A...)(A args)
>> 	{
>> 		eNew type = eNew.Default;
>> 		static if (A.length == 0 || !is(typeof(args[0]) == eNew))
>> 			alias nargs = args;
>> 		else
>> 		{
>> 			type = cast(eNew)args[0];
>> 			alias nargs = args[1..$];
>> 		}
>> 		
>> 		writeln(">> ",  __traits(classInstanceSize, T));
>> 		
>> 		switch (type)
>> 		{	
>> 			default: return new T(nargs);
>> 		}
>> 		
>> 		//return new T(nargs);
>> 	}
>> }
>>
>> class A
>> {
>> 	mixin iNew!A;
>> 	int t;
>> }
>>
>> class B : A
>> {
>> 	mixin iNew!B;
>> 	int q;
>> 	double d;
>> }
>>
>> void main()
>> {
>> 	A a = A.New();
>> 	B b = B.New();
>> 	readln();
>> }
>> ---
>
> Because I don't want to have to specify this in each class. 
> iNew is suppose to be a contract. What happens if someone 
> writes a class and forgets to add the mixin then distributes 
> the class in a library? There's no issue with that using an 
> interface because it results in an error.

I understand the goal. But if someone forgets to add the mixin, 
A.New() would not compile. And the probability of mistakenly 
calling 'new A' might even be as high as the probability of 
forgetting the mixin.


More information about the Digitalmars-d-learn mailing list