www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template Class With Default Values

reply bauss <jj_1337 live.dk> writes:
Why is the following not working?

class Foo(string baz = "baz")
{
     mixin("int " ~ baz ~ ";");
}

class Bar : Foo
{
}

Shouldn't it implicit do, without me having to do it manually?

class Bar : Foo!"baz"
{
}

...

What's the reason you can't specify default values for template 
parameters on a class? Is it intended behavior or is it a bug?

https://run.dlang.io/is/tnOtn3
Mar 04 2018
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, March 04, 2018 11:35:23 bauss via Digitalmars-d-learn wrote:
 Why is the following not working?

 class Foo(string baz = "baz")
 {
      mixin("int " ~ baz ~ ";");
 }

 class Bar : Foo
 {
 }

 Shouldn't it implicit do, without me having to do it manually?

 class Bar : Foo!"baz"
 {
 }

 ...

 What's the reason you can't specify default values for template
 parameters on a class? Is it intended behavior or is it a bug?

 https://run.dlang.io/is/tnOtn3
If it were allowed, it would be ambiguous. e.g. what would alias Foobar = Foo; mean? Would it be the default instantiation of Foo!"baz" or would it be the template itself? Right now, it's always the template itself, and in all cases except for functions, templates must be explicitly instantiated. For function templates, we have IFTI (Implicit Function Template Instantiation) where the compiler tries to infer the template arguments based on the function arguments. It works because the function call syntax is unambiguous such that if you have auto foo(T = string)(T t) {...} alias foobar = foo; it's guaranteed that foobar is the template foo and not an instantiation. It would certainly be possible to make the compiler implicitly instantiate templates that aren't functions under specific circumstances, but it can't be done in the general case, so rather than creating a situation with subtle rules about when it's necessary to explicitly instantiate a template and when it's not, it's simply always required to explicitly instantiate templates other than function templates. And based on Walter's comment in the associated enhancement request, he has concerns that allowing implicit template instantiations like this would cause serious problems. https://issues.dlang.org/show_bug.cgi?id=1012 Really, this is one of those things that at first seems like it's crazy that it doesn't work, but as the details become clearer, it starts seeming a lot less reasonable to try to make it work. - Jonathan M Davis
Mar 04 2018
parent reply bauss <jj_1337 live.dk> writes:
On Sunday, 4 March 2018 at 11:57:12 UTC, Jonathan M Davis wrote:
 On Sunday, March 04, 2018 11:35:23 bauss via 
 Digitalmars-d-learn wrote:
 Why is the following not working?

 class Foo(string baz = "baz")
 {
      mixin("int " ~ baz ~ ";");
 }

 class Bar : Foo
 {
 }

 Shouldn't it implicit do, without me having to do it manually?

 class Bar : Foo!"baz"
 {
 }

 ...

 What's the reason you can't specify default values for 
 template parameters on a class? Is it intended behavior or is 
 it a bug?

 https://run.dlang.io/is/tnOtn3
If it were allowed, it would be ambiguous. e.g. what would alias Foobar = Foo; mean? Would it be the default instantiation of Foo!"baz" or would it be the template itself? Right now, it's always the template itself, and in all cases except for functions, templates must be explicitly instantiated. For function templates, we have IFTI (Implicit Function Template Instantiation) where the compiler tries to infer the template arguments based on the function arguments. It works because the function call syntax is unambiguous such that if you have auto foo(T = string)(T t) {...} alias foobar = foo; it's guaranteed that foobar is the template foo and not an instantiation. It would certainly be possible to make the compiler implicitly instantiate templates that aren't functions under specific circumstances, but it can't be done in the general case, so rather than creating a situation with subtle rules about when it's necessary to explicitly instantiate a template and when it's not, it's simply always required to explicitly instantiate templates other than function templates. And based on Walter's comment in the associated enhancement request, he has concerns that allowing implicit template instantiations like this would cause serious problems. https://issues.dlang.org/show_bug.cgi?id=1012 Really, this is one of those things that at first seems like it's crazy that it doesn't work, but as the details become clearer, it starts seeming a lot less reasonable to try to make it work. - Jonathan M Davis
It wouldn't be ambiguous if it had same behavior as every other templates. Ex. void foo(string a = "a")() { writeln(a); } alias foo2 = foo; // Error ... The class situation should be the same. Which forces you to do alias foob = foo!"b"; Which means that the following would work properly: foo; foo!"b"; foob; Which is why it doesn't seem right that classes can't work the same way.
Mar 04 2018
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, March 04, 2018 14:43:41 bauss via Digitalmars-d-learn wrote:
 On Sunday, 4 March 2018 at 11:57:12 UTC, Jonathan M Davis wrote:
 On Sunday, March 04, 2018 11:35:23 bauss via

 Digitalmars-d-learn wrote:
 Why is the following not working?

 class Foo(string baz = "baz")
 {

      mixin("int " ~ baz ~ ";");

 }

 class Bar : Foo
 {
 }

 Shouldn't it implicit do, without me having to do it manually?

 class Bar : Foo!"baz"
 {
 }

 ...

 What's the reason you can't specify default values for
 template parameters on a class? Is it intended behavior or is
 it a bug?

 https://run.dlang.io/is/tnOtn3
If it were allowed, it would be ambiguous. e.g. what would alias Foobar = Foo; mean? Would it be the default instantiation of Foo!"baz" or would it be the template itself? Right now, it's always the template itself, and in all cases except for functions, templates must be explicitly instantiated. For function templates, we have IFTI (Implicit Function Template Instantiation) where the compiler tries to infer the template arguments based on the function arguments. It works because the function call syntax is unambiguous such that if you have auto foo(T = string)(T t) {...} alias foobar = foo; it's guaranteed that foobar is the template foo and not an instantiation. It would certainly be possible to make the compiler implicitly instantiate templates that aren't functions under specific circumstances, but it can't be done in the general case, so rather than creating a situation with subtle rules about when it's necessary to explicitly instantiate a template and when it's not, it's simply always required to explicitly instantiate templates other than function templates. And based on Walter's comment in the associated enhancement request, he has concerns that allowing implicit template instantiations like this would cause serious problems. https://issues.dlang.org/show_bug.cgi?id=1012 Really, this is one of those things that at first seems like it's crazy that it doesn't work, but as the details become clearer, it starts seeming a lot less reasonable to try to make it work. - Jonathan M Davis
It wouldn't be ambiguous if it had same behavior as every other templates. Ex. void foo(string a = "a")() { writeln(a); } alias foo2 = foo; // Error ... The class situation should be the same. Which forces you to do alias foob = foo!"b"; Which means that the following would work properly: foo; foo!"b"; foob; Which is why it doesn't seem right that classes can't work the same way.
Except that aliasing templates of any kind is legal. So, alias foo2 = foo; is legal just like alias bar = isInputRange; is legal. And in all cases, it aliases the template, not the instantiation, whether there are default template arguments or not. It only aliases the instantiation if the template is explicitly instantiated in the alias. There's nothing special about class or struct templates here, and the only thing special about function templates is that we have IFTI, which only kicks in when a function template is called. - Jonathan M Davis
Mar 04 2018
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Sunday, 4 March 2018 at 11:35:23 UTC, bauss wrote:
 Why is the following not working?

 class Foo(string baz = "baz")
 {
     mixin("int " ~ baz ~ ";");
 }

 class Bar : Foo
 {
 }

 Shouldn't it implicit do, without me having to do it manually?

 class Bar : Foo!"baz"
 {
 }
class Bar : Foo!() { }
Mar 04 2018
parent bauss <jj_1337 live.dk> writes:
On Sunday, 4 March 2018 at 11:59:52 UTC, Mike Parker wrote:
 On Sunday, 4 March 2018 at 11:35:23 UTC, bauss wrote:
 Why is the following not working?

 class Foo(string baz = "baz")
 {
     mixin("int " ~ baz ~ ";");
 }

 class Bar : Foo
 {
 }

 Shouldn't it implicit do, without me having to do it manually?

 class Bar : Foo!"baz"
 {
 }
class Bar : Foo!() { }
Still seems unneccessary.
Mar 04 2018