www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - default args for templates

reply Manu <turkeyman gmail.com> writes:
--001a113309641111ef04f0298a7a
Content-Type: text/plain; charset=UTF-8

Observing strange behaviour, just want to know if it's correct...

struct VertexBuffer(VertexDataType = void) {}

VertexBuffer x;
  Error: struct VertexBuffer(VertexDataType = void) is used as a type

auto y = VertexBuffer();
  Error: struct VertexBuffer(VertexDataType = void) cannot deduce template
function from argument types !()()

But this works:
VertexBuffer!() z;


Why should I need to supply an empty argument list? This defeats the
purpose of the default arg, and obscures my code in the common case.

Untyped vertex buffers are the default, and it would be nice to be able to
declare them trivially.

Also, those error messages are quite unhelpful.

--001a113309641111ef04f0298a7a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Observing strange behaviour, just want to know if it&#39;s=
 correct...<div><br></div><div><div>struct VertexBuffer(VertexDataType =3D =
void) {}</div></div><div><br></div><div>VertexBuffer x;<br></div><div>=C2=
=A0 Error: struct VertexBuffer(VertexDataType =3D void) is used as a type<b=
r>
</div><div><br></div><div>auto y =3D VertexBuffer();</div><div>=C2=A0 Error=
: struct VertexBuffer(VertexDataType =3D void) cannot deduce template funct=
ion from argument types !()()<br></div><div><br></div><div>But this works:<=
/div>
<div>VertexBuffer!() z;</div><div><br><br></div><div>Why should I need to s=
upply an empty argument list? This defeats the purpose of the default arg, =
and obscures my code in the common case.</div><div><br></div><div>Untyped v=
ertex buffers are the default, and it would be nice to be able to declare t=
hem trivially.</div>
<div><br></div><div>Also, those error messages are quite unhelpful.</div></=
div>

--001a113309641111ef04f0298a7a--
Jan 17 2014
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-01-17 13:18, Manu wrote:
 Observing strange behaviour, just want to know if it's correct...

 struct VertexBuffer(VertexDataType = void) {}

 VertexBuffer x;
    Error: struct VertexBuffer(VertexDataType = void) is used as a type

 auto y = VertexBuffer();
    Error: struct VertexBuffer(VertexDataType = void) cannot deduce
 template function from argument types !()()

 But this works:
 VertexBuffer!() z;


 Why should I need to supply an empty argument list? This defeats the
 purpose of the default arg, and obscures my code in the common case.

 Untyped vertex buffers are the default, and it would be nice to be able
 to declare them trivially.

 Also, those error messages are quite unhelpful.

Yeah, that's a really annoying limitation. I'm wonder if there's a bugzilla entry for it. -- /Jacob Carlborg
Jan 17 2014
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-01-17 13:53, bearophile wrote:

 If the instantiation is automatic, then what's the literal to specify
 the un-instantiated template?

Perhaps based on the context, but that might be a bad idea. -- /Jacob Carlborg
Jan 17 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-01-17 14:44, Dicebot wrote:

 I think it is impossible in general case:

 pragma(msg, StructSymbol.stringof); // "StructSymbol" or
 "StructSymbol!(void)" ?

 Add aliases on top of it and it quickly gets messy.

The compiler would first try the template symbol, if that fails try the instantiation. -- /Jacob Carlborg
Jan 17 2014
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2014-01-17 15:47, bearophile wrote:

 I don't think so. If you pass one of those literals to a template by
 alias, you are passing the template name (the type constructor) or the
 instantiated template (the type)? Both are valid usages and I think the
 compiler can't choose by itself. So I think this is a bad idea.

Template name, because you can override that with !() to mean template instantiation. -- /Jacob Carlborg
Jan 17 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Jacob Carlborg:

 Yeah, that's a really annoying limitation. I'm wonder if 
 there's a bugzilla entry for it.

If the instantiation is automatic, then what's the literal to specify the un-instantiated template? Bye, bearophile
Jan 17 2014
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Friday, 17 January 2014 at 12:18:51 UTC, Manu wrote:
 Observing strange behaviour, just want to know if it's 
 correct...

 struct VertexBuffer(VertexDataType = void) {}

 VertexBuffer x;
   Error: struct VertexBuffer(VertexDataType = void) is used as 
 a type

 auto y = VertexBuffer();
   Error: struct VertexBuffer(VertexDataType = void) cannot 
 deduce template
 function from argument types !()()

 But this works:
 VertexBuffer!() z;


 Why should I need to supply an empty argument list? This 
 defeats the
 purpose of the default arg, and obscures my code in the common 
 case.

 Untyped vertex buffers are the default, and it would be nice to 
 be able to
 declare them trivially.

 Also, those error messages are quite unhelpful.

There's enough subtlety in function identifiers vs function results due to optional parenthesis, I'd rather not have the same for templates too. Even if it could be made unambiguous, it would likely get pretty confusing.
Jan 17 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Friday, 17 January 2014 at 13:40:05 UTC, Jacob Carlborg wrote:
 On 2014-01-17 13:53, bearophile wrote:

 If the instantiation is automatic, then what's the literal to 
 specify
 the un-instantiated template?

Perhaps based on the context, but that might be a bad idea.

I think it is impossible in general case: pragma(msg, StructSymbol.stringof); // "StructSymbol" or "StructSymbol!(void)" ? Add aliases on top of it and it quickly gets messy.
Jan 17 2014
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--001a11c2c4849e7c3a04f02ad05b
Content-Type: text/plain; charset=UTF-8

On 17 January 2014 22:53, bearophile <bearophileHUGS lycos.com> wrote:

 Jacob Carlborg:


  Yeah, that's a really annoying limitation. I'm wonder if there's a
 bugzilla entry for it.

If the instantiation is automatic, then what's the literal to specify the un-instantiated template?

The context gives everything it needs. It's clearly being used to declare a variable. --001a11c2c4849e7c3a04f02ad05b Content-Type: text/html; charset=UTF-8 <div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 17 January 2014 22:53, bearophile <span dir="ltr">&lt;<a href="mailto:bearophileHUGS lycos.com" target="_blank">bearophileHUGS lycos.com</a>&gt;</span> wrote:<br> <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Jacob Carlborg:<div class="im"><br> <br> <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> Yeah, that&#39;s a really annoying limitation. I&#39;m wonder if there&#39;s a bugzilla entry for it.<br> </blockquote> <br></div> If the instantiation is automatic, then what&#39;s the literal to specify the un-instantiated template?<br></blockquote><div><br></div><div>The context gives everything it needs. It&#39;s clearly being used to declare a variable.</div> </div></div></div> --001a11c2c4849e7c3a04f02ad05b--
Jan 17 2014
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Friday, 17 January 2014 at 12:18:51 UTC, Manu wrote:
 Observing strange behaviour, just want to know if it's 
 correct...

 struct VertexBuffer(VertexDataType = void) {}

 VertexBuffer x;
   Error: struct VertexBuffer(VertexDataType = void) is used as 
 a type

 auto y = VertexBuffer();
   Error: struct VertexBuffer(VertexDataType = void) cannot 
 deduce template
 function from argument types !()()

 But this works:
 VertexBuffer!() z;


 Why should I need to supply an empty argument list? This 
 defeats the
 purpose of the default arg, and obscures my code in the common 
 case.

 Untyped vertex buffers are the default, and it would be nice to 
 be able to
 declare them trivially.

 Also, those error messages are quite unhelpful.

The funny part though is that it works if the template is a function. //---- template foo(T = int) { T foo(); } void main() { foo(); //Calls foo!int.foo(); } //---- I guess it's the "()" that saves our butts. Without it, we need explicit instantiation: //---- template foo(T = int) { T foo(); } void main() { pragma(msg, typeof(foo).stringof); pragma(msg, typeof(foo!int).stringof); } //---- void int() //----
Jan 17 2014
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Manu:

 The context gives everything it needs.

I don't think so. If you pass one of those literals to a template by alias, you are passing the template name (the type constructor) or the instantiated template (the type)? Both are valid usages and I think the compiler can't choose by itself. So I think this is a bad idea. Bye, bearophile
Jan 17 2014