1

Why do I need to mark functions that satisfy the criteria for constant-expression as constexpr to actually use them as constant expression?

Take this example (from here):

template<int N>
 class list
 { };

 constexpr int sqr1(int arg)
 { return arg * arg; }

 int sqr2(int arg)
 { return arg * arg; }

 int main()
 {
   const int X = 2;
   list<sqr1(X)> mylist1;  // OK: sqr1 is constexpr
   list<sqr2(X)> mylist2;  // wrong: sqr2 is not constexpr
 }

why do I have to mark sqr2 as constexpr? Isn't the compiler able to understand that that function satisfies the criteria for constant-expression? If it does the check for sqr1, why can't it do it for sqr2 and allow sqr2 to be used as a constant expression even without explicitly marking it?

Michele Piccolini
  • 2,634
  • 16
  • 29

1 Answers1

-1

All template parameters must be known at compile time. Template is just recipe to create code. Code is generated when template is instantiated with all required template parameters.

So list<sqr2(X)> fails, since sqr2 can't be evaluated at compile time. Only constexpr (or consteval) functions can be evaluated at compile time.

Marek R
  • 32,568
  • 6
  • 55
  • 140
  • This is how C++ works, granted. My question was "why does C++ works this way". Why can't the compiler check `sqr2` at compile-time and decide whether it can evaluate it or not. My understanding is that it capable of doing that - for example it performs this check on `sqr1` to see whether you can mark it with `constexpr` or not. – Michele Piccolini Feb 07 '22 at 15:52