2

For constexpr functions the only option is to have recursive functions for anything but simple things. The problem with that is that recursive functions are expensive at run time (especially if you are going to be calling yourself a lot of times).

So is it possible to implement 2 functions one for constexpr and the other for normal use:

constexpr int fact(int x){  //Use this at compile time
  return x == 0 ? 1 : fact(x-1)*x;
}

int fact(int x){  //Use this for real calls
  int ret = 1;
  for (int i = 1; i < x+1; i++){
    ret *= i;
  }
  return ret;
}

And along the same lines can you make a special function for inline situations also?

DarthRubik
  • 3,927
  • 1
  • 18
  • 54
  • How is a compile time construct expensive at run time? It may be harder to compile but the point is that at runtime it takes no time. – Martin York May 03 '16 at 00:19
  • 1
    @Loki For example if I don't know what I am passing to it (like input from user...that can not be calculated at runtime) – DarthRubik May 03 '16 at 00:44
  • You might check whether your compiler provides tail call optimization. [The major ones do when optimization is turned up](https://stackoverflow.com/questions/34125/which-if-any-c-compilers-do-tail-recursion-optimization) (and that information is from eight years ago), which would make the recursive function work just like the explicit loop. – ShadowRanger May 03 '16 at 00:57
  • @ShadowRanger I see...that is nice – DarthRubik May 03 '16 at 01:01
  • @ShadowRanger His recursive function isn't tail-recursive, it multiplies the recursive call. – Barmar May 03 '16 at 01:09
  • 2
    Have you read other similar questions? For example that: http://stackoverflow.com/questions/8936549/constexpr-overloading – Öö Tiib May 03 '16 at 01:12
  • The simplest solution is to give them different names: `fact_const` and `fact`. Use `fact_const` when you're calling it with compile-time literals. – Barmar May 03 '16 at 01:15
  • Why don't you just use the second one for both cases and make it `constexpr` ? – M.M May 03 '16 at 04:18

1 Answers1

3

Since C++14, the loop form is a valid constexpr as per (http://en.cppreference.com/w/cpp/language/constexpr), so the second form with constexpr added is valid. Unfortunately not all compilers support this (The latest version of Visual C++ doesn't, but the latest Clang and GCC ones apparently do (but I am unable to test this)).

In which case you can either:

  • Rely on the compilers optimizations, and use the first version (you might want to test this for your specific compiler)
  • Give the two forms different names (such as fact_const for the constexpr function, and make sure you only use the constexpr version when it's arguments are also constexpr (I don't know how to actually check whether this is the case)
  • Wait till your compiler releases an update that supports this.
Isaac
  • 816
  • 5
  • 12