On Wed, Apr 05, 2017 at 08:08:32PM +0000, Yuxuan Shui via Digitalmars-d wrote: > On Wednesday, 5 April 2017 at 16:06:39 UTC, H. S. Teoh wrote: > > On Wed, Apr 05, 2017 at 11:20:28AM +0000, Yuxuan Shui via Digitalmars-d > > wrote: > > > [...] > > > > Did you read the entire article? > > > > There is an entire section dedicated to interleaving of CTFE and > > templates. And no, you still cannot run CTFE on the same part of > > the AST that is being template-expanded. But you *can* run CTFE on a > > subtree that has already been fully expanded. > > > > And no, the forum post you linked to has nothing to do with CTFE. > > The so-called "static foreach" is unrolled at AST expansion time, > > and is not run through CTFE at all (unless later on you call the > > expanded function at "compile-time"). And is() expressions are also > > not CTFE, they are also evaluated at AST expansion time. > > > > Read the entire article first. ;-) > > > > > > T > > I was talking about the use of R.front, R.drop in the template.
Yes, that's the interleaving I was talking about. In your code example, R is an alias to something outside the template itself, so as long as whatever it aliases can be "finalized" in its AST, it can be handed to the CTFE engine for evaluation. This is really just a more fancy instance of the more common `enum X = f(Y);` idiom, but it's really the same thing. The compiler tries to use CTFE every time it sees a value that's needed at "compile-time"; `enum` is the usual way to trigger this, but a template expansion that depends on the value, as you have here, is also where the same thing happens. What you *cannot* have, though, is if R is in the process of being AST-expanded. E.g., if .front itself requires expandRange() in its definition, then it won't work, because then the compiler can't finalize the AST of .front and CTFE won't be able to run it. T -- Nobody is perfect. I am Nobody. -- pepoluan, GKC forum