www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Tempated class instantiation

reply Mike L. <sgtmuffles myrealbox.com> writes:
I'm making a class template that only works with strings, so I thought it'd be
good to instantiate each template with char, wchar, and dchar right in the
template's module so that when it's compiled it'll be part of the .obj file and
won't have to compile it for every other project that uses it. However, I get
an error reproducible with this:

module test;

class A(T)
{
	version(broken)
	{
		class B
		{
			T blah() { return t; }
		}
	}
	
	T t;
}

mixin A!(int);

int main()
{
	A!(int) a = new A!(int)();
	return 0;
}

If what I want to do makes sense, how should I be doing it?
Dec 15 2009
next sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
On Wed, 16 Dec 2009 07:25:39 +0100, Mike L. <sgtmuffles myrealbox.com>  
wrote:

 I'm making a class template that only works with strings, so I thought  
 it'd be good to instantiate each template with char, wchar, and dchar  
 right in the template's module so that when it's compiled it'll be part  
 of the .obj file and won't have to compile it for every other project  
 that uses it. However, I get an error reproducible with this:

 module test;

 class A(T)
 {
 	version(broken)
 	{
 		class B
 		{
 			T blah() { return t; }
 		}
 	}
 	
 	T t;
 }

 mixin A!(int);

 int main()
 {
 	A!(int) a = new A!(int)();
 	return 0;
 }

 If what I want to do makes sense, how should I be doing it?
It makes sense. Seems to be another compiler bug, but I have no good overview of which (might even be a new one). This compiles and runs: class A(T) { version(broken) { class B { // Explicitly state which t we're talking about. T blah() { return this.outer.t; } } } T t; } mixin A!(int); int main() { A!(int) a = new A!(int)(); return 0; } -- Simen
Dec 16 2009
parent reply Mike L. <sgtmuffles myrealbox.com> writes:
Simen kjaeraas Wrote:

 On Wed, 16 Dec 2009 07:25:39 +0100, Mike L. <sgtmuffles myrealbox.com>  
 wrote:
 
 I'm making a class template that only works with strings, so I thought  
 it'd be good to instantiate each template with char, wchar, and dchar  
 right in the template's module so that when it's compiled it'll be part  
 of the .obj file and won't have to compile it for every other project  
 that uses it. However, I get an error reproducible with this:

 module test;

 class A(T)
 {
 	version(broken)
 	{
 		class B
 		{
 			T blah() { return t; }
 		}
 	}
 	
 	T t;
 }

 mixin A!(int);

 int main()
 {
 	A!(int) a = new A!(int)();
 	return 0;
 }

 If what I want to do makes sense, how should I be doing it?
It makes sense. Seems to be another compiler bug, but I have no good overview of which (might even be a new one). This compiles and runs: class A(T) { version(broken) { class B { // Explicitly state which t we're talking about. T blah() { return this.outer.t; } } } T t; } mixin A!(int); int main() { A!(int) a = new A!(int)(); return 0; } -- Simen
Thanks for the reply, that seems to be working for my project too, but the code gets really ugly really fast. Should I submit a bug report? --Mike L.
Dec 16 2009
next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Mike L. <sgtmuffles myrealbox.com> wrote:

 Thanks for the reply, that seems to be working for my project too, but  
 the code gets really ugly really fast. Should I submit a bug report?
Please do. Even if it has a workaround, it's still a bug. -- Simen
Dec 16 2009
prev sibling parent reply Rory McGuire <rjmcguire gmail.com> writes:
Mike L. <sgtmuffles myrealbox.com> wrote:
 
 Simen kjaeraas Wrote:
 
 On Wed, 16 Dec 2009 07:25:39 +0100, Mike L. <sgtmuffles myrealbox.com>  
 wrote:
 
 I'm making a class template that only works with strings, so I thought  
 it'd be good to instantiate each template with char, wchar, and dchar  
 right in the template's module so that when it's compiled it'll be part  
 of the .obj file and won't have to compile it for every other project  
 that uses it. However, I get an error reproducible with this:

 module test;

 class A(T)
 {
  version(broken)
  {
   class B
   {
    T blah() { return t; }
   }
  }
  
  T t;
 }

 mixin A!(int);

 int main()
 {
  A!(int) a = new A!(int)();
  return 0;
 }

 If what I want to do makes sense, how should I be doing it?
It makes sense. Seems to be another compiler bug, but I have no good overview of which (might even be a new one). This compiles and runs: class A(T) { version(broken) { class B { // Explicitly state which t we're talking about. T blah() { return this.outer.t; } } } T t; } mixin A!(int); int main() { A!(int) a = new A!(int)(); return 0; } -- Simen
Thanks for the reply, that seems to be working for my project too, but the
code gets really ugly really fast. Should I submit a bug report?
 
 --Mike L.
 
As grauzone said, you have to use an alias, or you could use a template. but the code above just does the same old templated class instantiation, you can leave out the mixin A!(int); line completely. As far as I understand it a template is always evaluated at least once for each type T. So perhaps if you used it in the module that declares it the compiler would detect that it doesn't need to compile it again but I'm not convinced of that because the instance is in a different module. -Rory
Dec 16 2009
parent Mike L. <sgtmuffles myrealbox.com> writes:
Rory McGuire Wrote:

 Mike L. <sgtmuffles myrealbox.com> wrote:
  
 Simen kjaeraas Wrote:
 
 On Wed, 16 Dec 2009 07:25:39 +0100, Mike L. <sgtmuffles myrealbox.com>  
 wrote:
 
 I'm making a class template that only works with strings, so I thought  
 it'd be good to instantiate each template with char, wchar, and dchar  
 right in the template's module so that when it's compiled it'll be part  
 of the .obj file and won't have to compile it for every other project  
 that uses it. However, I get an error reproducible with this:

 module test;

 class A(T)
 {
  version(broken)
  {
   class B
   {
    T blah() { return t; }
   }
  }
  
  T t;
 }

 mixin A!(int);

 int main()
 {
  A!(int) a = new A!(int)();
  return 0;
 }

 If what I want to do makes sense, how should I be doing it?
It makes sense. Seems to be another compiler bug, but I have no good overview of which (might even be a new one). This compiles and runs: class A(T) { version(broken) { class B { // Explicitly state which t we're talking about. T blah() { return this.outer.t; } } } T t; } mixin A!(int); int main() { A!(int) a = new A!(int)(); return 0; } -- Simen
Thanks for the reply, that seems to be working for my project too, but the
code gets really ugly really fast. Should I submit a bug report?
 
 --Mike L.
 
As grauzone said, you have to use an alias, or you could use a template. but the code above just does the same old templated class instantiation, you can leave out the mixin A!(int); line completely. As far as I understand it a template is always evaluated at least once for each type T. So perhaps if you used it in the module that declares it the compiler would detect that it doesn't need to compile it again but I'm not convinced of that because the instance is in a different module. -Rory
So it sounds like my best bet is to just make a bogus alias. I guess I probably couldn't do something like mixin A!(int) and mixin A!(char), because each would create a class named A and there would be a naming conflict. --Mike L.
Dec 17 2009
prev sibling parent grauzone <none example.net> writes:
Mike L. wrote:
 I'm making a class template that only works with strings, so I thought it'd be
good to instantiate each template with char, wchar, and dchar right in the
template's module so that when it's compiled it'll be part of the .obj file and
won't have to compile it for every other project that uses it. However, I get
an error reproducible with this:
 
 module test;
 
 class A(T)
 {
 	version(broken)
 	{
 		class B
 		{
 			T blah() { return t; }
 		}
 	}
 	
 	T t;
 }
 
 mixin A!(int);
 
 int main()
 {
 	A!(int) a = new A!(int)();
 	return 0;
 }
 
 If what I want to do makes sense, how should I be doing it?
AFAIK it works if you do alias B!(int) Something; If you want to get the above code to work, use template A(T) instead of class A(T) + mixin.
Dec 16 2009