www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template with default parameter

reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
I have simple template:
```d
template T(int i=3)
{
     mixin template M(int m)
     {
	    enum t = i;
     }
}

{
	mixin T!1.M!1;
	pragma(msg, t);   // 1
}
{
	mixin T!().M!1;
	pragma(msg, t);   // 3
}
{
	mixin T.M!1;      // Error: identifier `M` of `T.M` is not 
defined
					  // Error: mixin `M!1` is not defined
	pragma(msg, t);   // Error: undefined identifier `t`
					  //        while evaluating `pragma(msg, t)`
}
```

What should I do to be able to write `T.M!...`? I want to omit 
verbose `!()` for `T`. Note that mixins are essential here.
Mar 10 2022
parent reply bauss <jj_1337 live.dk> writes:
On Friday, 11 March 2022 at 04:41:40 UTC, Andrey Zherikov wrote:
 I have simple template:
 ```d
 template T(int i=3)
 {
     mixin template M(int m)
     {
 	    enum t = i;
     }
 }

 {
 	mixin T!1.M!1;
 	pragma(msg, t);   // 1
 }
 {
 	mixin T!().M!1;
 	pragma(msg, t);   // 3
 }
 {
 	mixin T.M!1;      // Error: identifier `M` of `T.M` is not 
 defined
 					  // Error: mixin `M!1` is not defined
 	pragma(msg, t);   // Error: undefined identifier `t`
 					  //        while evaluating `pragma(msg, t)`
 }
 ```

 What should I do to be able to write `T.M!...`? I want to omit 
 verbose `!()` for `T`. Note that mixins are essential here.
Create an alias for T!() is the best you can do. Ex. ``` alias t = T!(); ``` There isn't really any better method as far as I know.
Mar 10 2022
parent reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
On Friday, 11 March 2022 at 07:06:15 UTC, bauss wrote:
 Create an alias for T!() is the best you can do.

 Ex.

 ```
 alias t = T!();
 ```

 There isn't really any better method as far as I know.
I'd like to preserve the name (`t` != `T`) but `alias T = T!()` gives me `Error: declaration `T` is already defined`
Mar 11 2022
next sibling parent bauss <jj_1337 live.dk> writes:
On Friday, 11 March 2022 at 11:55:24 UTC, Andrey Zherikov wrote:
 On Friday, 11 March 2022 at 07:06:15 UTC, bauss wrote:
 Create an alias for T!() is the best you can do.

 Ex.

 ```
 alias t = T!();
 ```

 There isn't really any better method as far as I know.
I'd like to preserve the name (`t` != `T`) but `alias T = T!()` gives me `Error: declaration `T` is already defined`
Yeah you can't really do much about that. Then T would have to be something like TImpl and then you do `alias T = TImpl!();`
Mar 11 2022
prev sibling parent reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
There is some inconsistency between templates and template 
functions as this works as I want to:
```d
import std.stdio;

void f(int i=3)()
{
     writeln(i);
}

void main()
{
     f!1;  // 1
     f!(); // 3
     f;    // 3
}
```
Mar 11 2022
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 3/11/22 04:01, Andrey Zherikov wrote:
 There is some inconsistency between templates and template functions as
 this works as I want to:
 ```d
 import std.stdio;

 void f(int i=3)()
 {
      writeln(i);
 }

 void main()
 {
      f!1;  // 1
      f!(); // 3
      f;    // 3
 }
 ```
Reduced: template T(int i = 3) { enum value = i; } void main() { pragma(msg, T!().value); // Requires T!() } The same inconsistency exists for user-defined type templates as well: struct S(int i = 3) { } void main() { S!() s; // Requires S!() } There has been requests to remove this inconsistency. Might be in bugzilla. Ali
Mar 11 2022
prev sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Friday, 11 March 2022 at 12:01:27 UTC, Andrey Zherikov wrote:
 There is some inconsistency between templates and template 
 functions as this works as I want to:
Yeah, functions have the special feature of implicit instantiation from the function arguments. No other template do, if you want an instance there, you need to specify it as a !(). And since functions can't return aliases to types you can't use that to get around it. There's no way to do what you want to do, you either need to write the !() or use a different alias name.
Mar 11 2022
parent Andrey Zherikov <andrey.zherikov gmail.com> writes:
On Friday, 11 March 2022 at 12:53:56 UTC, Adam D Ruppe wrote:
 On Friday, 11 March 2022 at 12:01:27 UTC, Andrey Zherikov wrote:
 There is some inconsistency between templates and template 
 functions as this works as I want to:
Yeah, functions have the special feature of implicit instantiation from the function arguments. No other template do, if you want an instance there, you need to specify it as a !(). And since functions can't return aliases to types you can't use that to get around it. There's no way to do what you want to do, you either need to write the !() or use a different alias name.
Thanks for explanation!
Mar 11 2022