www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why a template with Nullable does not compile?

reply Victor Porton <porton narod.ru> writes:
Why does this not compile?

import std.typecons;

template FieldInfo(T, Nullable!T default_) {
}

/usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(2570,17): 
Error: `alias T = T;` cannot alias itself, use a qualified name 
to create an overload set
/usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(3291,17): 
Error: `alias T = T;` cannot alias itself, use a qualified name 
to create an overload set
Mar 11
next sibling parent Victor Porton <porton narod.ru> writes:
On Tuesday, 12 March 2019 at 05:14:21 UTC, Victor Porton wrote:
 Why does this not compile?

 import std.typecons;

 template FieldInfo(T, Nullable!T default_) {
 }

 /usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(2570,17): Error: `alias
T = T;` cannot alias itself, use a qualified name to create an overload set
 /usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(3291,17): Error: `alias
T = T;` cannot alias itself, use a qualified name to create an overload set
LDC - the LLVM D compiler (1.11.0): based on DMD v2.081.2 and LLVM 6.0.1
Mar 11
prev sibling parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Tuesday, 12 March 2019 at 05:14:21 UTC, Victor Porton wrote:
 Why does this not compile?

 import std.typecons;

 template FieldInfo(T, Nullable!T default_) {
 }

 /usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(2570,17): Error: `alias
T = T;` cannot alias itself, use a qualified name to create an overload set
 /usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(3291,17): Error: `alias
T = T;` cannot alias itself, use a qualified name to create an overload set
It seems to be getting confused between the two types of Nullable, namely: Nullable(T), and Nullable(T, T defaultVal) template FieldInfo(T) { template FieldInfo(Nullable!(T) default_) { enum FieldInfo = 0; } } seems to work, but I can't seem to instantiate one of it.
Mar 12
parent reply Victor Porton <porton narod.ru> writes:
template FieldInfo(T, Nullable!T default_) {
}

On Tuesday, 12 March 2019 at 09:05:36 UTC, Nicholas Wilson wrote:
 It seems to be getting confused between the two types of 
 Nullable, namely:
 Nullable(T), and
 Nullable(T, T defaultVal)
I don't understand why exactly it is getting confused. How can it decide that "Nullable!T default_" is a two-arguments template when it is so not "Nullable!(T, default_)"? Please explain the EXACT cause of the error.
 template FieldInfo(T) {
     template FieldInfo(Nullable!(T) default_)
     {
         enum FieldInfo = 0;
     }
 }

 seems to work, but I can't seem to instantiate one of it.
Why you use the same name "FieldInfo" for both the template and its subtemplate? Does it make some sense?
Mar 12
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Mar 12, 2019 at 03:26:05PM +0000, Victor Porton via Digitalmars-d-learn
wrote:
[...]
 On Tuesday, 12 March 2019 at 09:05:36 UTC, Nicholas Wilson wrote:
[...]
 template FieldInfo(T) {
     template FieldInfo(Nullable!(T) default_)
     {
         enum FieldInfo = 0;
     }
 }
 
 seems to work, but I can't seem to instantiate one of it.
Why you use the same name "FieldInfo" for both the template and its subtemplate? Does it make some sense?
This is a D idiom called the "eponymous template". Whenever the template contains a member of the same name as the template, it's an eponymous template, and you can refer directly to the member by the template name, rather than using templateName.memberName. For example, a template function is usually written like this: ReturnType myFunc(TemplateArgs...)(RuntimeArgs args...) { ... // implementation here } This is actually shorthand for the eponymous template: template myFunc(TemplateArgs...) { ReturnType myFunc(RuntimeArgs args...) { ... // implementation here } } Similarly, when you write: enum isInputRange(T) = hasMember!(T, empty) && ... that's actually shorthand for: template isInputRange(T) { enum isInputRange = hasMember!(T, empty) && ... } The eponymonus template idiom allows you to use a single name to refer to both the template and the member. Without this idiom, you'd have to use the very verbose notation: static if (isInputRange!T.isInputRange) ... or auto retval = myFunc!(A, B, C).myFunc(1, 2, 3); T -- It won't be covered in the book. The source code has to be useful for something, after all. -- Larry Wall
Mar 12
parent reply Victor Porton <porton narod.ru> writes:
On Tuesday, 12 March 2019 at 16:20:11 UTC, H. S. Teoh wrote:
 On Tue, Mar 12, 2019 at 03:26:05PM +0000, Victor Porton via 
 Digitalmars-d-learn wrote: [...]
 On Tuesday, 12 March 2019 at 09:05:36 UTC, Nicholas Wilson 
 wrote:
[...]
 template FieldInfo(T) {
     template FieldInfo(Nullable!(T) default_)
     {
         enum FieldInfo = 0;
     }
 }
 
 seems to work, but I can't seem to instantiate one of it.
Why you use the same name "FieldInfo" for both the template and its subtemplate? Does it make some sense?
This is a D idiom called the "eponymous template". Whenever the template contains a member of the same name as the template, it's an eponymous template, and you can refer directly to the member by the template name, rather than using templateName.memberName. For example, a template function is usually written like this: ReturnType myFunc(TemplateArgs...)(RuntimeArgs args...) { ... // implementation here } This is actually shorthand for the eponymous template: template myFunc(TemplateArgs...) { ReturnType myFunc(RuntimeArgs args...) { ... // implementation here } } Similarly, when you write: enum isInputRange(T) = hasMember!(T, empty) && ... that's actually shorthand for: template isInputRange(T) { enum isInputRange = hasMember!(T, empty) && ... } The eponymonus template idiom allows you to use a single name to refer to both the template and the member. Without this idiom, you'd have to use the very verbose notation: static if (isInputRange!T.isInputRange) ... or auto retval = myFunc!(A, B, C).myFunc(1, 2, 3);
I know what is eponymous template. But how it behaves when the eponymous member inside itself is also a template? How to instantiate it? (provide please an example how to instantiate)
Mar 12
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Mar 12, 2019 at 04:23:29PM +0000, Victor Porton via Digitalmars-d-learn
wrote:
[...]
 I know what is eponymous template. But how it behaves when the
 eponymous member inside itself is also a template? How to instantiate
 it? (provide please an example how to instantiate)
You need to provide two sets of template arguments. Usually, the only time we nest eponymous templates this way is when we're writing a function that needs to take two variadic sets of template parameters. In that case, we only need to write one set of template parameters and let IFTI fill in the second set of parameters for us. For example: template map(funcs...) { template map(Ranges...) { auto map(Ranges rr) { ... } } } auto r = map!(func1, func2)(r1, r2); The first part `map!(func1, func2)` resolves to an instantiation of the outer template, which is an inner template, then the compiler uses IFTI to deduce the second set of arguments as !(typeof(r1), typeof(r2)) in order to instantiate the inner template. If you want to instantiate it by hand, you could do something like this: alias Outer = map!(func1, func2); // instantiate outer template alias inner = Outer!(int[], int[]); // instantiate inner template inner([ 1, 2, 3], [ 4, 5, 6 ]); T -- People say I'm indecisive, but I'm not sure about that. -- YHL, CONLANG
Mar 12
prev sibling parent Victor Porton <porton narod.ru> writes:
On Tuesday, 12 March 2019 at 15:26:05 UTC, Victor Porton wrote:
 template FieldInfo(T, Nullable!T default_) {
 }

 On Tuesday, 12 March 2019 at 09:05:36 UTC, Nicholas Wilson 
 wrote:
 It seems to be getting confused between the two types of 
 Nullable, namely:
 Nullable(T), and
 Nullable(T, T defaultVal)
I don't understand why exactly it is getting confused. How can it decide that "Nullable!T default_" is a two-arguments template when it is so not "Nullable!(T, default_)"? Please explain the EXACT cause of the error.
My question why it is getting confused was not answered.
Mar 12