0

I created the following code to create a sequence of numbers from 0 to N inclusive. I'm aware there are better methods with O(log N) instantiation depth like here, but that isn't the focus.

#include <cstddef>

template<std::size_t... Ns> struct hasNums;

template<bool> struct hasBool;

template<std::size_t... Ns> 
hasNums<Ns...>* makeNums(hasBool<false>*);

template<std::size_t First, std::size_t... Ns> 
constexpr
decltype(makeNums<(First - 1),First,Ns...>(
static_cast<hasBool<static_cast<bool>(First - 1)>*>(0)
) ) makeNums(hasBool<true>*);

template<std::size_t... Ns>
void method(hasNums<Ns...>*){

}

int main()
{
    method(static_cast<decltype(makeNums<20>(static_cast<hasBool<true>*>(0)))>(0)) ;
  
}

Link to the code in cppinsights

Running the code on cppinsights reveals that only method is instantiated, and this is only so I can see that the numbers 0 to N are indeed being produced. I was surprised because I thought I'd see instantiations of makeNums too. How can the compiler create this index sequence without other instantiations?

  • Related to [function-template-instantiation-in-unevaluated-context](https://stackoverflow.com/questions/61840943/function-template-instantiation-in-unevaluated-context) – Jarod42 Apr 02 '21 at 15:40
  • What did you expect to see instantiated? There isn't even a body of `makeNums` available. Anyway `decltype` is an unevaluated context. The body isn't needed. – rustyx Apr 02 '21 at 15:55
  • @rustyx Something like `template<> constexpr decltype(makeNums<19,20>(static_cast*>(0)) makeNums<20>(hasBool*)`, the steps it took to make the sequence [N - 1, N], then [N - 2,N], etc. – Steve Zhang Apr 02 '21 at 15:59
  • Well I guess cppinsights shows only instantiated bodies... it looks like some kind of clang AST hack anyway... – rustyx Apr 02 '21 at 16:13

0 Answers0