2

I am very confused by why the following code doesn't compile:

template <typename T, typename... Ts> 
void TEST(T&& t, Ts&&... ts) {
  if constexpr(sizeof...(ts) > 0) {
    TEST(std::forward<Ts>(ts)...);
    static_assert( t == 2 , "parameter must be 2");
  }
}

template <typename... Ts> 
void VARIADIC(Ts&&... ts) {
  TEST(std::forward<Ts>(ts)...);
}

int main(int argc, char* argv[]) {
  constexpr int a1 = 2;
  constexpr int a2 = 2;
  VARIADIC(a1, a2);
}

Basically, I am trying to do some compile-time check on the parameters passed to the function VARIADIC. However, the compiler complained about the following:

error: non-constant condition for static assertion
     static_assert( t == 2 , "parameter must be 2");
     ^~~~~~~~~~~~~
error: ‘t’ is not a constant expression

It is very obvious the given parameters a1 and a2 are constants, and there must be some ways to perform the check on variadic arguments.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
Jes
  • 2,614
  • 4
  • 25
  • 45
  • Can we lose the all uppercase thing? –  May 07 '17 at 22:35
  • 2
    What is the confusion about? Entities are only treated as constant expression when they are introduced as part of a constant expression. Clearly, the parameters to a function are *not* constant expression in that sense. However, the function result *can* be a constant expression. – Dietmar Kühl May 07 '17 at 22:37
  • The error is in the definition of the TEST function, which could be called with non-constant values. The fact that you happen to be calling TEST with constant values doesn't matter. – Vaughn Cato May 07 '17 at 22:37
  • `t` is not a constant expression in your code. – Edward Strange May 07 '17 at 23:12
  • You could try the following: http://stackoverflow.com/questions/8626055/c11-static-assert-within-constexpr-function – jwimberley May 08 '17 at 01:53

1 Answers1

4

The function arguments are not core constant expressions according to 5.20 [expr.const] paragraph 2.9: variables or references are only core constant expressions if they are initialized with a constant expression or their live-time began within the definition of constant expression. Function arguments clearly satisfy neither.

The background is that constexpr functions can be called with run-time values. For the determination of whether a variable is a constant expression within the function it is immaterial whether it is actually called with a constant expression. Whether it matter whether the call is with a constant expression is when the function is evaluated: although the arguments do not behave as constant expressions within the function the result can still be a constant expression.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380