<br><br><div class="gmail_quote">On Thu, Jul 29, 2010 at 22:40, Jason Spencer <span dir="ltr">&lt;<a href="mailto:spencer8@sbcglobal.net">spencer8@sbcglobal.net</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
In writing templates that make heavy use of alias parameters, does<br>
anyone else feel uneasy about whether the caller will pass a type, a<br>
value, or a schmoo?  </blockquote><div><br></div><div>I thought they could only be symbols. That is, an alias is a &#39;link&#39;, a sort of pointer to a symbol: a template name, a module name, a function name, etc.</div>
<div>It does not seem to accept types:</div><div><br></div><div><div>template TestAlias(alias a)</div><div>{</div><div>    enum string TestAlias = __traits(identifier, a);</div><div>}</div><div><br></div><div>void main()</div>
<div>{</div><div>    T foo(T)(T t) { return t;}</div><div>    writeln(TestAlias!foo); // works</div><div>    writeln(TestAlias!int); // do not compile</div><div>}</div></div><div><br></div><div>Though &#39;3&#39; is accepted by alias... Hmm.</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">I&#39;m having a hard time getting my head around<br>
how wide-open aliases are and trying to resist the urge to put in<br>
thousands of static asserts to check what should be invariants on<br>
the kind of thing that can be passed in that position.  This all<br>
feels very strange when I typically look for templates to provide<br>
that nice, static, compile-time safety that keeps me from having to<br>
check everything that gets passed.  Any words of wisdom on adjusting<br>
to this feature?</blockquote><div><br></div><div>Wisdom, I don&#39;t know, as I still feel like I&#39;m exploring things. But template constraints are there to limit what you can instantiate. The C++ syntax is still there (T : U, etc), but it&#39;s quite limited and not so easy to parse, compared to D template constraints.</div>
<div><br></div><div>Feel free to ignore what follows if that&#39;s well-treaded ground to you.</div><div><br></div><div>Say I have a template that takes an alias, fun, and a type, T. </div><div>fun is supposed to be a function, but in fact why limit it to that? What I need is for foo to be callable with a T. So let&#39;s test for that:</div>
<div><br></div><div>auto doSomething(alias fun, T)(T t)</div><div>if (is(typeof( fun(T.init) )))</div><div>{ </div><div>// now that I&#39;m here, I can freely use fun as a callable on any T</div><div> auto result = fun(t);</div>
<div>// ...</div><div>}</div><div><br></div><div>So, T is a type. T.init is a value of type T, the default value for any T. .init is a easy way to generate a value from a type. Any type in D has a .init field (not typetuples, though). Note that &#39;t&#39; is not really accessible inside the constraint template, because t will have a runtime value, whereas here we are at compile-time. I think t can be used, but is still T.init at this stage.</div>
<div><br></div><div>I call fun with T.init. If that compiles, then the resulting expression has a type: I use typeof() to get it, and then the is() expression to get a bool telling me if that&#39;s a valid type. If foo(T.init) doesn&#39;t compile, for whatever reason (fun as no opCall defined, or foo is callable, but not with a T...) then foo(T.init) has no type, so is(typeof( ... )) returns false and the template constraint forbids the template to be instantiated.</div>
<div><br></div><div>inside doSomething(), I can freely use fun as something callable with one T.</div><div>Note that my constraint is not complete: I did not test for fun(T.init) to return a value: it could be a void function(T) and the assignement would fail. I could also test for that, I guess.</div>
<div><br></div><div>Philippe</div><div><br></div></div>