www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Question on Template Specializing.

reply "SteveGuo" <steveguo outlook.com> writes:
The following example can't be compiled.

// A.d
-------------------------------------

class A(T)
{
     T a;
}


// main.d
-------------------------------------
import A;

int main(string param[])
{
     A!(int) a;

     return 0;
}

Compiler complains with this message "Error: template instance 
A!(int) A is not a template declaration, it is a import"

So I read online documents, It says "TemplateInstantances are 
always performed in the scope of where the TemplateDeclaration is 
declared, with the addition of the template parameters being 
declared as aliases for their deduced types."

So, I modified the code as the following

// A.d
-------------------------------------

class A(T)
{
     T a;
}

alias A!(int) AInt;

// main.d
-------------------------------------
import A;

int main(string param[])
{
     AInt a;

     return 0;
}

This time it compiled successful.

But my question is:
If I am a library author, I write templates for my users, so 
users can specialize the template with any types they defined. I 
don't know what types they may define when I design the template, 
so how can I specialize the template for them in my template 
module?
Aug 06 2013
next sibling parent "evilrat" <evilrat666 gmail.com> writes:
On Wednesday, 7 August 2013 at 05:10:25 UTC, SteveGuo wrote:
 The following example can't be compiled.

 // A.d
 -------------------------------------

 class A(T)
 {
     T a;
 }


 // main.d
 -------------------------------------
 import A;

 int main(string param[])
 {
     A!(int) a;

     return 0;
 }

 Compiler complains with this message "Error: template instance 
 A!(int) A is not a template declaration, it is a import"

 So I read online documents, It says "TemplateInstantances are 
 always performed in the scope of where the TemplateDeclaration 
 is declared, with the addition of the template parameters being 
 declared as aliases for their deduced types."

 So, I modified the code as the following

 // A.d
 -------------------------------------

 class A(T)
 {
     T a;
 }

 alias A!(int) AInt;

 // main.d
 -------------------------------------
 import A;

 int main(string param[])
 {
     AInt a;

     return 0;
 }

 This time it compiled successful.

 But my question is:
 If I am a library author, I write templates for my users, so 
 users can specialize the template with any types they defined. 
 I don't know what types they may define when I design the 
 template, so how can I specialize the template for them in my 
 template module?

doh... most of such weird errors are due to module naming. module names should be always in lowercase(not neccessary but recommended), and the second, your problem is due to name conflict of module name and class name, just give your module a meaningful name and problem is gone. why is that? i think because alias has tighter lookup rules than "normal" code.
Aug 06 2013
prev sibling next sibling parent "evilrat" <evilrat666 gmail.com> writes:
On Wednesday, 7 August 2013 at 05:10:25 UTC, SteveGuo wrote:
 But my question is:
 If I am a library author, I write templates for my users, so 
 users can specialize the template with any types they defined. 
 I don't know what types they may define when I design the 
 template, so how can I specialize the template for them in my 
 template module?

if you want to make some presets for common types you can use aliases alias A!int Aint; alias A!float Afloat; ... if you want to enforce template accept only certain types you should use static asserts or type covariance(oh sorry it's not called this but i'm somehow stupid now) ------------- // type limitation with overloading interface Something { ... } // specialized template for covariants of Something(will be instantiated with any covariant of Something) class A(T: Something) { ... } // generic template(instantiated when no specialized overloads exists) class A(T) { } ------------- or static asserts/if ------------- import std.traits; class A(T) { // code for numeric types static if(isNumeric(T)) { ... } // code for callable objects static if(isCallable(T)) { } // and so on... }
Aug 06 2013
prev sibling next sibling parent "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
On Wednesday, 7 August 2013 at 05:31:07 UTC, evilrat wrote:
 On Wednesday, 7 August 2013 at 05:10:25 UTC, SteveGuo wrote:
 The following example can't be compiled.

 // A.d
 -------------------------------------

 class A(T)
 {
    T a;
 }


 // main.d
 -------------------------------------
 import A;

 int main(string param[])
 {
    A!(int) a;

    return 0;
 }

module names should be always in lowercase(not neccessary but recommended), and the second, your problem is due to name conflict of module name and class name, just give your module a meaningful name and problem is gone.

The name doesn't need to be changed, Instead main could have contain: A.A!(int) a; Instantiate A from module A (instead of instantiate module A which is the cause of the error)
Aug 06 2013
prev sibling parent "SteveGuo" <steveguo outlook.com> writes:
 The name doesn't need to be changed, Instead main could have 
 contain:

     A.A!(int) a;

 Instantiate A from module A (instead of instantiate module A 
 which is the cause of the error)

Thanks, It was compiled successfully!
Aug 06 2013