digitalmars.D.learn - Let this() figure out T implicitly?
- kraybourne <stdin kraybourne.com> Feb 17 2012
- bearophile <bearophileHUGS lycos.com> Feb 17 2012
- kraybourne <stdin kraybourne.com> Feb 17 2012
- Kevin Cox <kevincox.ca gmail.com> Feb 17 2012
- kraybourne <stdin kraybourne.com> Feb 17 2012
- Timon Gehr <timon.gehr gmx.ch> Feb 17 2012
- kraybourne <stdin kraybourne.com> Feb 17 2012
- Kevin Cox <kevincox.ca gmail.com> Feb 17 2012
- "Steven Schveighoffer" <schveiguy yahoo.com> Feb 17 2012
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> Feb 17 2012
- Timon Gehr <timon.gehr gmx.ch> Feb 17 2012
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> Feb 17 2012
- Timon Gehr <timon.gehr gmx.ch> Feb 17 2012
Hi!
This doesn't work:
import std.stdio;
class Foo(T)
{
T t;
this(T val)
{
t = val;
}
}
void main()
{
auto o = new Foo(5);
}
_____
$ dmd foo
foo.d(13): Error: class foo.Foo(T) is used as a type
$ _
So I must
auto o = new Foo!(int)(5);
Then it compiles. Is it possible to have this() figure out the type some
way? (In this particular example it's perhaps not such a big deal. But
imagine a lot more args.)
(Side note: What _does_ that error message mean? I don't get it.)
thanks
/krbrn
Feb 17 2012
kraybourne:Then it compiles. Is it possible to have this() figure out the type some way?
Usually people write a small global function helper.(Side note: What _does_ that error message mean? I don't get it.)
I think the meaning is: when a class template is not yet instantiated, it's not a type yet. Bye, bearophile
Feb 17 2012
On 2/17/12 1:32 PM, bearophile wrote:kraybourne:Then it compiles. Is it possible to have this() figure out the type some way?
Usually people write a small global function helper.
Hm, so, something like this: Foo!(T) newFoo(T)(T val) { return new Foo!(T)(val); } ... auto o = newFoo(5); Works! Ha! How silly. Thanks!(Side note: What _does_ that error message mean? I don't get it.)
I think the meaning is: when a class template is not yet instantiated, it's not a type yet. Bye, bearophile
Feb 17 2012
--00151740269ce686b504b9286726 Content-Type: text/plain; charset=UTF-8 The error message is saying that you are trying to use Foo as a type but Foo is not a type, it is a template for a type. On Feb 17, 2012 7:20 AM, "kraybourne" <stdin kraybourne.com> wrote:Hi! This doesn't work: import std.stdio; class Foo(T) { T t; this(T val) { t = val; } } void main() { auto o = new Foo(5); } _____ $ dmd foo foo.d(13): Error: class foo.Foo(T) is used as a type $ _ So I must auto o = new Foo!(int)(5); Then it compiles. Is it possible to have this() figure out the type some way? (In this particular example it's perhaps not such a big deal. But imagine a lot more args.) (Side note: What _does_ that error message mean? I don't get it.) thanks /krbrn
--00151740269ce686b504b9286726 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <p>The error message is saying that you are trying to use Foo as a type but= Foo is not a type, it is a template for a type.</p> <div class=3D"gmail_quote">On Feb 17, 2012 7:20 AM, "kraybourne" = <<a href=3D"mailto:stdin kraybourne.com">stdin kraybourne.com</a>> wr= ote:<br type=3D"attribution"><blockquote class=3D"gmail_quote" style=3D"mar= gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> Hi!<br> <br> This doesn't work:<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0import std.stdio;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0class Foo(T)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0T t;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0this(T val)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0t =3D val;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0void main()<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0auto o =3D new Foo(= 5);<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0_____<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0$ dmd foo<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0foo.d(13): Error: class foo.Foo(T) is used as a= type<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0$ _<br> <br> So I must<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0auto o =3D new Foo!(int)(5);<br> <br> Then it compiles. Is it possible to have this() figure out the type some wa= y? (In this particular example it's perhaps not such a big deal. But im= agine a lot more args.)<br> <br> (Side note: What _does_ that error message mean? I don't get it.)<br> <br> thanks<br> /krbrn<br> </blockquote></div> --00151740269ce686b504b9286726--
Feb 17 2012
On 2/17/12 1:51 PM, Kevin Cox wrote:The error message is saying that you are trying to use Foo as a type but Foo is not a type, it is a template for a type.
Ah, so module.Foo is really not a class, but a template? I think I get it! Thanks! (Is then module.Foo(int).Foo the actual class type? I think I've seen errors like that pop up...)On Feb 17, 2012 7:20 AM, "kraybourne" <stdin kraybourne.com <mailto:stdin kraybourne.com>> wrote: Hi! This doesn't work: import std.stdio; class Foo(T) { T t; this(T val) { t = val; } } void main() { auto o = new Foo(5); } _____ $ dmd foo foo.d(13): Error: class foo.Foo(T) is used as a type $ _ So I must auto o = new Foo!(int)(5); Then it compiles. Is it possible to have this() figure out the type some way? (In this particular example it's perhaps not such a big deal. But imagine a lot more args.) (Side note: What _does_ that error message mean? I don't get it.) thanks /krbrn
Feb 17 2012
On 02/17/2012 02:07 PM, Kevin Cox wrote:Yes. At least as the compiler would say. It's a little odd but I believe that is how the D Nam mangling works. I personally just think of Foo!(Class) as the type.
class Foo(T){ ... } Is syntactic sugar for template Foo(T){ class Foo{ ... } } Therefore the type is Foo!(Class).Foo. I'd prefer the compiler to output Foo!(Class) in error messages and for .stringof though, vote here: http://d.puremagic.com/issues/show_bug.cgi?id=7064
Feb 17 2012
On 2/17/12 2:38 PM, Timon Gehr wrote:On 02/17/2012 02:07 PM, Kevin Cox wrote:Yes. At least as the compiler would say. It's a little odd but I believe that is how the D Nam mangling works. I personally just think of Foo!(Class) as the type.
class Foo(T){ ... } Is syntactic sugar for template Foo(T){ class Foo{ ... } } Therefore the type is Foo!(Class).Foo.
Aaah, I see, clever, thxI'd prefer the compiler to output Foo!(Class) in error messages and for .stringof though, vote here: http://d.puremagic.com/issues/show_bug.cgi?id=7064
Feb 17 2012
--00151740269ccbbaca04b928a0bd Content-Type: text/plain; charset=UTF-8 Yes. At least as the compiler would say. It's a little odd but I believe that is how the D Nam mangling works. I personally just think of Foo!(Class) as the type. On Feb 17, 2012 8:05 AM, "kraybourne" <stdin kraybourne.com> wrote:On 2/17/12 1:51 PM, Kevin Cox wrote:The error message is saying that you are trying to use Foo as a type but Foo is not a type, it is a template for a type.
Thanks! (Is then module.Foo(int).Foo the actual class type? I think I've seen errors like that pop up...) On Feb 17, 2012 7:20 AM, "kraybourne" <stdin kraybourne.com<mailto:stdin kraybourne.com>> wrote: Hi! This doesn't work: import std.stdio; class Foo(T) { T t; this(T val) { t = val; } } void main() { auto o = new Foo(5); } _____ $ dmd foo foo.d(13): Error: class foo.Foo(T) is used as a type $ _ So I must auto o = new Foo!(int)(5); Then it compiles. Is it possible to have this() figure out the type some way? (In this particular example it's perhaps not such a big deal. But imagine a lot more args.) (Side note: What _does_ that error message mean? I don't get it.) thanks /krbrn
--00151740269ccbbaca04b928a0bd Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <p>Yes.=C2=A0 At least as the compiler would say.=C2=A0 It's a little o= dd but I believe that is how the D Nam mangling works.=C2=A0 I personally j= ust think of Foo!(Class) as the type.</p> <div class=3D"gmail_quote">On Feb 17, 2012 8:05 AM, "kraybourne" = <<a href=3D"mailto:stdin kraybourne.com">stdin kraybourne.com</a>> wr= ote:<br type=3D"attribution"><blockquote class=3D"gmail_quote" style=3D"mar= gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> On 2/17/12 1:51 PM, Kevin Cox wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> The error message is saying that you are trying to use Foo as a type but<br=
<br> </blockquote> <br> Ah, so module.Foo is really not a class, but a template? I think I get it! = Thanks!<br> <br> (Is then module.Foo(int).Foo the actual class type? I think I've seen e= rrors like that pop up...)<br> <br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> On Feb 17, 2012 7:20 AM, "kraybourne" <<a href=3D"mailto:stdin= kraybourne.com" target=3D"_blank">stdin kraybourne.com</a><br> <mailto:<a href=3D"mailto:stdin kraybourne.com" target=3D"_blank">stdin = kraybourne.com</a>>> wrote:<br> <br> =C2=A0 =C2=A0Hi!<br> <br> =C2=A0 =C2=A0This doesn't work:<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0import std.stdio;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0class Foo(T)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0T t;<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0this(= T val)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0t =3D val;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0void main()<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0auto = o =3D new Foo(5);<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0_____<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0$ dmd foo<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0foo.d(13): Error: class foo.Foo(T= ) is used as a type<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0$ _<br> <br> =C2=A0 =C2=A0So I must<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0auto o =3D new Foo!(int)(5);<br> <br> =C2=A0 =C2=A0Then it compiles. Is it possible to have this() figure out th= e type<br> =C2=A0 =C2=A0some way? (In this particular example it's perhaps not su= ch a big<br> =C2=A0 =C2=A0deal. But imagine a lot more args.)<br> <br> =C2=A0 =C2=A0(Side note: What _does_ that error message mean? I don't = get it.)<br> <br> =C2=A0 =C2=A0thanks<br> =C2=A0 =C2=A0/krbrn<br> <br> </blockquote> <br> </blockquote></div> --00151740269ccbbaca04b928a0bd--
Feb 17 2012
On Fri, 17 Feb 2012 07:19:28 -0500, kraybourne <stdin kraybourne.com> wrote:Hi! This doesn't work: import std.stdio; class Foo(T) { T t; this(T val) { t = val; } } void main() { auto o = new Foo(5); } _____ $ dmd foo foo.d(13): Error: class foo.Foo(T) is used as a type $ _ So I must auto o = new Foo!(int)(5); Then it compiles. Is it possible to have this() figure out the type some way? (In this particular example it's perhaps not such a big deal. But imagine a lot more args.)
What you are asking for is IFTI (Implicit Function Template Instantiation) on constructors, and is perfectly possible, but not implemented: http://d.puremagic.com/issues/show_bug.cgi?id=6082 Vote up if you want to see it happen! -Steve
Feb 17 2012
On 02/17/2012 09:08 AM, Steven Schveighoffer wrote:What you are asking for is IFTI (Implicit Function Template Instantiation) on constructors, and is perfectly possible, but not implemented: http://d.puremagic.com/issues/show_bug.cgi?id=6082
What was the resolution for the case when the constructor is a template? I think that's why IFTI doesn't work for structs and classes in C++. Although, I can't get the following to compile in D anyway (that old and annoying error message again! :p): Error: no property 'opCall' for type 'deneme.B' import std.conv; class B { string s; this(T)(T t) // <-- Is the struct a template // or the constructor a template? { s = to!string(t); } } void main() { auto b0 = B(42); } I wasn't around when the static opCall() was designed but it is probably the very first thing that bugged me about D. :) I want B(42) to be object construction, not opCall(), which is not even defined. Ali
Feb 17 2012
On 02/18/2012 12:04 AM, Ali Çehreli wrote:On 02/17/2012 09:08 AM, Steven Schveighoffer wrote: > What you are asking for is IFTI (Implicit Function Template > Instantiation) on constructors, and is perfectly possible, but not > implemented: > > http://d.puremagic.com/issues/show_bug.cgi?id=6082 What was the resolution for the case when the constructor is a template? I think that's why IFTI doesn't work for structs and classes in C++. Although, I can't get the following to compile in D anyway (that old and annoying error message again! :p): Error: no property 'opCall' for type 'deneme.B' import std.conv; class B { string s; this(T)(T t) // <-- Is the struct a template // or the constructor a template?
The constructor it is, and B is a class, not a struct.{ s = to!string(t); } } void main() { auto b0 = B(42); } I wasn't around when the static opCall() was designed but it is probably the very first thing that bugged me about D. :) I want B(42) to be object construction, not opCall(), which is not even defined. Ali
Why? What useful semantics would that have for classes?
Feb 17 2012
On 02/17/2012 05:59 PM, Timon Gehr wrote:On 02/18/2012 12:04 AM, Ali Çehreli wrote:On 02/17/2012 09:08 AM, Steven Schveighoffer wrote:What you are asking for is IFTI (Implicit Function Template Instantiation) on constructors, and is perfectly possible, but not implemented: http://d.puremagic.com/issues/show_bug.cgi?id=6082
What was the resolution for the case when the constructor is a template? I think that's why IFTI doesn't work for structs and classes in C++. Although, I can't get the following to compile in D anyway (that old and annoying error message again! :p): Error: no property 'opCall' for type 'deneme.B' import std.conv; class B { string s; this(T)(T t) // <-- Is the struct a template // or the constructor a template?
The constructor it is, and B is a class, not a struct.
Ah! Thanks! So today the following works; and not B, but the constructor is a template: import std.conv; struct B { string s; this(T)(T t) // <-- constructor is a template { s = to!string(t); } } void main() { auto b0 = B(42); // construct with int assert(b0.s == "42"); auto b1 = B(1.5); // construct with double assert(b1.s == "1.5"); } With the proposed feature, the struct would be a template.{ s = to!string(t); } } void main() { auto b0 = B(42); } I wasn't around when the static opCall() was designed but it is probably the very first thing that bugged me about D. :) I want B(42) to be object construction, not opCall(), which is not even defined. Ali
Why? What useful semantics would that have for classes?
I am not sure but the point is, if function templates provide IFTI, then because of being functions the constructors could provide IFTI as well, as it does for the struct B above. As an aside, I don't know why it is not the same with classes. I hope I am not again making an error in the following code. I have replaced 'struct' with 'class' and inserted two 'new' keywords: import std.conv; class B { string s; this(T)(T t) { s = to!string(t); } } void main() { auto b0 = new B(42); // line 61459 assert(b0.s == "42"); auto b1 = new B(1.5); // line 61462 assert(b1.s == "1.5"); } The compiler says: deneme.d(61459): Error: no constructor for B deneme.d(61462): Error: no constructor for B deneme.d(61462): Warning: statement is not reachable Ali
Feb 17 2012
On 02/18/2012 03:22 AM, Ali Çehreli wrote:On 02/17/2012 05:59 PM, Timon Gehr wrote: > On 02/18/2012 12:04 AM, Ali Çehreli wrote: >> On 02/17/2012 09:08 AM, Steven Schveighoffer wrote: >> >> > What you are asking for is IFTI (Implicit Function Template >> > Instantiation) on constructors, and is perfectly possible, but not >> > implemented: >> > >> > http://d.puremagic.com/issues/show_bug.cgi?id=6082 >> >> What was the resolution for the case when the constructor is a template? >> I think that's why IFTI doesn't work for structs and classes in C++. >> Although, I can't get the following to compile in D anyway (that old and >> annoying error message again! :p): >> >> Error: no property 'opCall' for type 'deneme.B' >> >> import std.conv; >> >> class B >> { >> string s; >> >> this(T)(T t) // <-- Is the struct a template >> // or the constructor a template? > > The constructor it is, and B is a class, not a struct. Ah! Thanks! So today the following works; and not B, but the constructor is a template: import std.conv; struct B { string s; this(T)(T t) // <-- constructor is a template { s = to!string(t); } } void main() { auto b0 = B(42); // construct with int assert(b0.s == "42"); auto b1 = B(1.5); // construct with double assert(b1.s == "1.5"); } With the proposed feature, the struct would be a template.
With the proposed feature still the constructor would be a template. The proposed feature is just that IFTI for constructors should be able to deduce the parameters for the enclosing struct/class template additionally to just its own parameters.>> { >> s = to!string(t); >> } >> } >> >> void main() >> { >> auto b0 = B(42); >> } >> >> I wasn't around when the static opCall() was designed but it is probably >> the very first thing that bugged me about D. :) I want B(42) to be >> object construction, not opCall(), which is not even defined. >> >> Ali >> > > Why? What useful semantics would that have for classes? I am not sure but the point is, if function templates provide IFTI, then because of being functions the constructors could provide IFTI as well, as it does for the struct B above. As an aside, I don't know why it is not the same with classes. I hope I am not again making an error in the following code. I have replaced 'struct' with 'class' and inserted two 'new' keywords: import std.conv; class B { string s; this(T)(T t) { s = to!string(t); } } void main() { auto b0 = new B(42); // line 61459 assert(b0.s == "42"); auto b1 = new B(1.5); // line 61462 assert(b1.s == "1.5"); } The compiler says: deneme.d(61459): Error: no constructor for B deneme.d(61462): Error: no constructor for B deneme.d(61462): Warning: statement is not reachable Ali
This seems to be a bug.
Feb 17 2012









kraybourne <stdin kraybourne.com> 