Phobos has a number of <b>non-function template</b> traits (std.traits, std.typetuple etc), eg:<br><br>---- in std.traits:<br>template hasMember(T, string name) {<br>    static if (is(T == struct) || is(T == class) || is(T == union) || is(T == interface))<br>
        enum bool hasMember =<br>            staticIndexOf!(name, __traits(allMembers, T)) != -1 ||<br>            __traits(compiles, { mixin("alias Identity!(T."~name~") Sym;"); });<br>    else<br>        enum bool hasMember = false;<br>
}<br>----<br><br>I see those <b>disadvantages</b> with non-function templates:<div><br>* syntax is less clear than regular function templates (there's no way to tell the return type without looking at the code or using some convention relating to the template name)<br>
<br></div><div>* they're not DRY, as the template name is typically repeated (maybe in multiple places) inside the template body (hasMember appears 3 times here)</div><div><br></div><div>* behavior of templates is actually weird, for example:</div>
<div><br></div><div>----</div><div>



<font face="Menlo">
<span style="color:#009695">template</span><span style="color:#444444"> </span><span style="color:#444444">A1</span><span style="color:#444444">(</span><span style="color:#444444">T</span><span style="color:#444444">)</span><span style="color:#444444">{</span><span style="color:#009695">enum</span><span style="color:#444444"> </span><span style="color:#444444">A1</span><span style="color:#444444">=</span><span style="color:#f57d00">0</span><span style="color:#444444">;</span><span style="color:#444444">}</span><br>

<span style="color:#009695">template</span><span style="color:#444444"> </span><span style="color:#444444">A2</span><span style="color:#444444">(</span><span style="color:#444444">T</span><span style="color:#444444">)</span><span style="color:#444444">{</span><span style="color:#009695">enum</span><span style="color:#444444"> </span><span style="color:#444444">B</span><span style="color:#444444">=</span><span style="color:#f57d00">0</span><span style="color:#444444">;</span><span style="color:#444444">}</span><br>

<span style="color:#009695">template</span><span style="color:#444444"> </span><span style="color:#444444">A3</span><span style="color:#444444">(</span><span style="color:#444444">T</span><span style="color:#444444">)</span><span style="color:#444444">{</span><span style="color:#009695">enum</span><span style="color:#444444"> </span><span style="color:#444444">A3</span><span style="color:#444444">=</span><span style="color:#f57d00">0</span><span style="color:#444444">;</span><span style="color:#009695">enum</span><span style="color:#444444"> </span><span style="color:#444444">B</span><span style="color:#444444">=</span><span style="color:#f57d00">0</span><span style="color:#444444">;</span><span style="color:#444444">}</span><br>

<span style="color:#009695">void</span><span style="color:#444444"> </span><span style="color:#444444">main</span><span style="color:#444444">(</span><span style="color:#444444">)</span><span style="color:#444444">{</span><br>

<span style="color:#444444">    </span><span style="color:#009695">enum</span><span style="color:#444444"> </span><span style="color:#444444">a1</span><span style="color:#444444">=</span><span style="color:#444444">A1</span><span style="color:#444444">!</span><span style="color:#009695">int</span><span style="color:#444444">;</span><span style="color:#444444">    </span><span style="font-style:italic;color:#999988">//</span><span style="font-style:italic;color:#999988">ok</span><br>

<span style="color:#444444">    </span><span style="color:#009695">enum</span><span style="color:#444444"> </span><span style="color:#444444">a2</span><span style="color:#444444">=</span><span style="color:#444444">A2</span><span style="color:#444444">!</span><span style="color:#009695">int</span><span style="color:#444444">.</span><span style="color:#444444">B</span><span style="color:#444444">;</span><span style="color:#444444">    </span><span style="font-style:italic;color:#999988">//</span><span style="font-style:italic;color:#999988">ok</span><br>

<span style="color:#444444">    </span><span style="font-style:italic;color:#999988">//</span><span style="font-style:italic;color:#999988">    </span><span style="font-style:italic;color:#999988">enum</span><span style="font-style:italic;color:#999988"> </span><span style="font-style:italic;color:#999988">a3</span><span style="font-style:italic;color:#999988">=</span><span style="font-style:italic;color:#999988">A3</span><span style="font-style:italic;color:#999988">!</span><span style="font-style:italic;color:#999988">int</span><span style="font-style:italic;color:#999988">.</span><span style="font-style:italic;color:#999988">B</span><span style="font-style:italic;color:#999988">;</span><span style="font-style:italic;color:#999988">    </span><span style="font-style:italic;color:#999988">/</span><span style="font-style:italic;color:#999988">/</span><span style="font-style:italic;color:#999988">Error</span><span style="font-style:italic;color:#999988">:</span><span style="font-style:italic;color:#999988"> </span><span style="font-style:italic;color:#999988">no</span><span style="font-style:italic;color:#999988"> </span><span style="font-style:italic;color:#999988">property</span><span style="font-style:italic;color:#999988"> </span><span style="font-style:italic;color:#999988">'</span><span style="font-style:italic;color:#999988">B</span><span style="font-style:italic;color:#999988">'</span><span style="font-style:italic;color:#999988"> </span><span style="font-style:italic;color:#999988">for</span><span style="font-style:italic;color:#999988"> </span><span style="font-style:italic;color:#999988">type</span><span style="font-style:italic;color:#999988"> </span><span style="font-style:italic;color:#999988">'</span><span style="font-style:italic;color:#999988">int</span><span style="font-style:italic;color:#999988">'</span><br>

<span style="color:#444444">}</span></font>

</div><div><div>----</div></div><div><br></div><div>Maybe this was for historical reasons (ie CTFE might've come after those design patterns were invented).</div><div><br></div><div>I would propose to use <b>regular template functions</b> instead, whenever possible (essentially for the ones that return a value):</div>
<div><br></div><div>For our example, this would become:</div><div>----</div><div>



<font face="Menlo">
<span style="color:#009695">bool</span><span style="color:#444444"> </span><span style="color:#444444">hasMember</span><span style="color:#444444">(</span><span style="color:#444444">T</span><span style="color:#444444">,</span><span style="color:#444444"> </span><span style="color:#009695">string</span><span style="color:#444444"> </span><span style="color:#444444">name</span><span style="color:#444444">)</span><span style="color:#444444">(</span><span style="color:#444444">)</span><span style="color:#444444">{</span><br>

<span style="color:#444444">    </span><span style="color:#009695">static</span><span style="color:#444444"> </span><span style="color:#009695">if</span><span style="color:#444444"> </span><span style="color:#444444">(</span><span style="color:#009695">is</span><span style="color:#444444">(</span><span style="color:#444444">T</span><span style="color:#444444"> </span><span style="color:#444444">=</span><span style="color:#444444">=</span><span style="color:#444444"> </span><span style="color:#009695">struct</span><span style="color:#444444">)</span><span style="color:#444444"> </span><span style="color:#444444">|</span><span style="color:#444444">|</span><span style="color:#444444"> </span><span style="color:#009695">is</span><span style="color:#444444">(</span><span style="color:#444444">T</span><span style="color:#444444"> </span><span style="color:#444444">=</span><span style="color:#444444">=</span><span style="color:#444444"> </span><span style="color:#009695">class</span><span style="color:#444444">)</span><span style="color:#444444"> </span><span style="color:#444444">|</span><span style="color:#444444">|</span><span style="color:#444444"> </span><span style="color:#009695">is</span><span style="color:#444444">(</span><span style="color:#444444">T</span><span style="color:#444444"> </span><span style="color:#444444">=</span><span style="color:#444444">=</span><span style="color:#444444"> </span><span style="color:#009695">union</span><span style="color:#444444">)</span><span style="color:#444444"> </span><span style="color:#444444">|</span><span style="color:#444444">|</span><span style="color:#444444"> </span><span style="color:#009695">is</span><span style="color:#444444">(</span><span style="color:#444444">T</span><span style="color:#444444"> </span><span style="color:#444444">=</span><span style="color:#444444">=</span><span style="color:#444444"> </span><span style="color:#009695">interface</span><span style="color:#444444">)</span><span style="color:#444444">)</span><br>
<span style="color:#444444">    </span><span style="color:#444444">    </span><span style="color:#009695">return</span><span style="color:#444444"> </span><span style="color:#444444">staticIndexOf</span><span style="color:#444444">!</span><span style="color:#444444">(</span><span style="color:#444444">name</span><span style="color:#444444">,</span><span style="color:#444444"> </span><span style="color:#009695">__traits</span><span style="color:#444444">(</span><span style="color:#444444">allMembers</span><span style="color:#444444">,</span><span style="color:#444444"> </span><span style="color:#444444">T</span><span style="color:#444444">)</span><span style="color:#444444">)</span><span style="color:#444444"> </span><span style="color:#444444">!</span><span style="color:#444444">=</span><span style="color:#444444"> </span><span style="color:#444444">-</span><span style="color:#f57d00">1</span><span style="color:#444444"> </span><span style="color:#444444">|</span><span style="color:#444444">|</span><br>

<span style="color:#444444">    </span><span style="color:#444444">    </span><span style="color:#444444">    </span><span style="color:#444444">    </span><span style="color:#009695">__traits</span><span style="color:#444444">(</span><span style="color:#444444">compiles</span><span style="color:#444444">,</span><span style="color:#444444"> </span><span style="color:#444444">{</span><span style="color:#444444"> </span><span style="color:#009695">mixin</span><span style="color:#444444">(</span><span style="color:#f57d00">"</span><span style="color:#f57d00">alias Identity!(T.</span><span style="color:#f57d00">"</span><span style="color:#444444">~</span><span style="color:#444444">name</span><span style="color:#444444">~</span><span style="color:#f57d00">"</span><span style="color:#f57d00">) Sym;</span><span style="color:#f57d00">"</span><span style="color:#444444">)</span><span style="color:#444444">;</span><span style="color:#444444"> </span><span style="color:#444444">}</span><span style="color:#444444">)</span><span style="color:#444444">;</span><br>
<span style="color:#444444">    </span><span style="color:#009695">else </span></font><span style="font-family:Menlo;color:rgb(0,150,149)">return</span><span style="font-family:Menlo;color:rgb(68,68,68)"> </span><span style="font-family:Menlo;color:rgb(0,150,149)">false</span><span style="font-family:Menlo;color:rgb(68,68,68)">;</span><font face="Menlo"><br>
<span style="color:#444444">}</span><br>
</font></div><div><font face="Menlo"><span style="color:#444444">// can be used in exactly the same way:</span></font></div><div><font face="Menlo"><span style="color:#444444">static assert(hasMember!(A,"field"));</span></font></div>
<div><div>----</div></div><div><br></div><div><b>Advantages</b>:</div><div><div>* clear syntax: returns bool, and body is simpler to read as well</div></div><div><div>* DRY: <span style="color:rgb(68,68,68);font-family:Menlo">hasMember only mentioned once</span></div>
</div><div><div>* no weird behavior as above</div></div><div>* <span style="color:rgb(68,68,68);font-family:Menlo">doesn't break any code as usage is the same (backwards compatible)</span></div><div><font color="#444444" face="Menlo"><br>
</font></div><div>In fact, I was able to convert with no problems a number of other such templates:</div><div>



<font face="Menlo">
<span style="color:#444444"></span><span style="color:#444444">staticIndexOf</span></font>

</div><div>



<font face="Menlo">
<span style="color:#444444"></span><span style="color:#444444">isSame</span></font>

</div><div>



<font face="Menlo">
<span style="color:#444444"></span><span style="color:#444444">expectType</span></font>

</div><div>



<font face="Menlo">
<span style="color:#444444"></span><span style="color:#444444">genericIndexOf</span></font>

</div><div><font face="Menlo"><span style="color:#444444">etc...</span></font></div><div><br></div><div>For the latter (<span style="color:rgb(68,68,68);font-family:Menlo">genericIndexOf)</span>, the template body contained a clause like that:</div>
<div>



<font face="Menlo">
<span style="color:#444444"></span><span style="color:#009695">enum</span><span style="color:#444444"> </span><span style="color:#444444">next</span><span style="color:#444444"> </span><span style="color:#444444"> </span><span style="color:#444444">=</span><span style="color:#444444"> </span><span style="color:#444444">genericIndexOf</span><span style="color:#444444">!</span><span style="color:#444444">(</span><span style="color:#444444">e</span><span style="color:#444444">,</span><span style="color:#444444"> </span><span style="color:#444444">tail</span><span style="color:#444444">)</span><span style="color:#444444">.</span><span style="color:#444444">index</span><span style="color:#444444">;</span><br>
<span style="color:#009695">enum</span><span style="color:#444444"> </span><span style="color:#444444">index</span><span style="color:#444444"> </span><span style="color:#444444">=</span><span style="color:#444444"> </span><span style="color:#444444">(</span><span style="color:#444444">next</span><span style="color:#444444"> </span><span style="color:#444444">=</span><span style="color:#444444">=</span><span style="color:#444444"> </span><span style="color:#444444">-</span><span style="color:#f57d00">1</span><span style="color:#444444">)</span><span style="color:#444444"> </span><span style="color:#444444">?</span><span style="color:#444444"> </span><span style="color:#444444">-</span><span style="color:#f57d00">1</span><span style="color:#444444"> </span><span style="color:#444444">:</span><span style="color:#444444"> </span><span style="color:#f57d00">1</span><span style="color:#444444"> </span><span style="color:#444444">+</span><span style="color:#444444"> </span><span style="color:#444444">next</span><span style="color:#444444">;</span><br>
</font></div><div>during conversion, I just had to add the line:</div><div><div><font face="Menlo"><span style="color:rgb(0,150,149)">return</span><span style="color:rgb(68,68,68)"> </span><span style="color:rgb(68,68,68)">Tuple</span><span style="color:rgb(68,68,68)">!</span><span style="color:rgb(68,68,68)">(</span><span style="color:rgb(0,150,149)">int</span><span style="color:rgb(68,68,68)">,</span><span style="color:rgb(68,68,68)"> </span><span style="color:rgb(245,125,0)">"</span><span style="color:rgb(245,125,0)">index</span><span style="color:rgb(245,125,0)">"</span><span style="color:rgb(68,68,68)">,</span><span style="color:rgb(0,150,149)">int</span><span style="color:rgb(68,68,68)">,</span><span style="color:rgb(68,68,68)"> </span><span style="color:rgb(245,125,0)">"</span><span style="color:rgb(245,125,0)">next</span><span style="color:rgb(245,125,0)">"</span><span style="color:rgb(68,68,68)">)</span><span style="color:rgb(68,68,68)">(</span><span style="color:rgb(68,68,68)">index</span><span style="color:rgb(68,68,68)">,</span><span style="color:rgb(68,68,68)">next</span><span style="color:rgb(68,68,68)">)</span><span style="color:rgb(68,68,68)">;</span></font></div>
</div><div>which could further be simplified using a helper function as its a common idiom, into:</div><div><div><div><font face="Menlo"><span style="color:rgb(0,150,149)">return</span><span style="color:rgb(68,68,68)"> </span><span style="color:rgb(68,68,68)">TupleNamed</span><span style="color:rgb(68,68,68)">!</span><span style="color:rgb(68,68,68)">(</span><span style="color:rgb(245,125,0)">"</span><span style="color:rgb(245,125,0)">index</span><span style="color:rgb(245,125,0)">"</span><span style="color:rgb(68,68,68)">,</span><span style="color:rgb(245,125,0)">"</span><span style="color:rgb(245,125,0)">next</span><span style="color:rgb(245,125,0)">"</span><span style="color:rgb(68,68,68)">)</span><span style="color:rgb(68,68,68)">(</span><span style="color:rgb(68,68,68)">index</span><span style="color:rgb(68,68,68)">,</span><span style="color:rgb(68,68,68)">next</span><span style="color:rgb(68,68,68)">)</span><span style="color:rgb(68,68,68)">;</span></font></div>
</div></div><div><font face="Menlo"><span style="color:rgb(68,68,68)"><br></span></font></div><div><br></div><div><b>Limitations</b>: </div><div>One typical case where this isn't possible is when a template defines an type alias, eg:</div>
<div>----</div><div><font face="Menlo"><span style="color:#009695">template</span><span style="color:#444444"> </span><span style="color:#444444">Iota</span><span style="color:#444444">(</span><span style="color:#009695">int</span><span style="color:#444444"> </span><span style="color:#444444">stop</span><span style="color:#444444">)</span><span style="color:#444444"> </span><span style="color:#444444">{</span><br>

<span style="color:#444444">    </span><span style="color:#009695">static</span><span style="color:#444444"> </span><span style="color:#009695">if</span><span style="color:#444444"> </span><span style="color:#444444">(</span><span style="color:#444444">stop</span><span style="color:#444444"> </span><span style="color:#444444"><</span><span style="color:#444444">=</span><span style="color:#444444"> </span><span style="color:#f57d00">0</span><span style="color:#444444">)</span><br>

<span style="color:#444444">    </span><span style="color:#444444">    </span><span style="color:#009695">alias</span><span style="color:#444444"> </span></font><span style="color:rgb(68,68,68);font-family:Menlo">Iota=</span><span style="font-family:Menlo;color:rgb(68,68,68)">TypeTuple</span><span style="font-family:Menlo;color:rgb(68,68,68)">!</span><span style="font-family:Menlo;color:rgb(68,68,68)">(</span><span style="font-family:Menlo;color:rgb(68,68,68)">)</span><span style="font-family:Menlo;color:rgb(68,68,68)">;</span></div>
<div><font face="Menlo">
<span style="color:#444444">    </span><span style="color:#009695">else</span><br>
<span style="color:#444444">    </span><span style="color:#444444">    </span><span style="color:#009695">alias</span><span style="color:#444444"> </span></font><span style="color:rgb(68,68,68);font-family:Menlo">Iota=</span><span style="font-family:Menlo;color:rgb(68,68,68)">TypeTuple</span><span style="font-family:Menlo;color:rgb(68,68,68)">!</span><span style="font-family:Menlo;color:rgb(68,68,68)">(</span><span style="font-family:Menlo;color:rgb(68,68,68)">Iota</span><span style="font-family:Menlo;color:rgb(68,68,68)">!</span><span style="font-family:Menlo;color:rgb(68,68,68)">(</span><span style="font-family:Menlo;color:rgb(68,68,68)">stop</span><span style="font-family:Menlo;color:rgb(68,68,68)">-</span><span style="font-family:Menlo;color:rgb(245,125,0)">1</span><span style="font-family:Menlo;color:rgb(68,68,68)">)</span><span style="font-family:Menlo;color:rgb(68,68,68)">,</span><span style="font-family:Menlo;color:rgb(68,68,68)"> </span><span style="font-family:Menlo;color:rgb(68,68,68)">stop</span><span style="font-family:Menlo;color:rgb(68,68,68)">-</span><span style="font-family:Menlo;color:rgb(245,125,0)">1)</span><span style="font-family:Menlo;color:rgb(68,68,68)">;</span></div>
<div><font face="Menlo">
<span style="color:#444444">}</span></font>  <br><div>----</div><div><br></div><br><br></div>