0
#include <iostream>

using namespace std;

template <int fact>
constexpr int pow2T()
{
    static_assert(fact < 0, "error");
return fact == 0 ? 1 : pow2T<fact - 1>() * 2;
}

constexpr int e2 = pow2T<2>();

int main(int argc, char *argv[])
{
    cout << e2 << endl;

   return 0;
}

Trying to implement x^2 static calculation with argument static checking. Assertion fails.. why!?

/home/serj/work/untitled/main.cpp:-1: In function 'constexpr int pow2T() [with int fact = 2]':

/home/serj/work/untitled/main.cpp:-1: In function 'constexpr int pow2T() [with int fact = 1]':

...

Piotr Skotnicki
  • 46,953
  • 7
  • 118
  • 160
noname7619
  • 3,370
  • 3
  • 21
  • 26

2 Answers2

7

static_assert fails if condition is false. Obviously, 1 < 0 and 2 < 0 are both false.

BTW, this function computes 2^x, not x^2

Artem Sobolev
  • 5,891
  • 1
  • 22
  • 40
3

The 2 branches are evaluated, you have to do specialization:

template <int fact>
constexpr int pow2T()
{
    static_assert(fact >= 0, "error");
    return pow2T<fact - 1>() * 2;
}

template <>
constexpr int pow2T<0>()
{
    return 1;
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • My compiler agrees with you. But could you say why ?: version does not work as expected? Taking into account I'm trying to calculate only powT(2). – noname7619 Jan 07 '15 at 15:39
  • `pow2T<2>` requires `pow2T<1>` which requires `pow2T<0>`. But `pow2T<0>` also requires `pow2T<-1>` as the 2 branches are instranciated (even if it is not evaluated). – Jarod42 Jan 07 '15 at 16:14