constexpr function are generally more readable as they are regular functions.
Caveats that it can be used in runtime even with compile time constant argument (at call site).
constexpr int f(int n) { /*...*/ }
constexpr int f5 = f(5); // Compile time.
int f4 = f(4); // Runtime time (compiler can optimize as for non-constexpr functions though)
For runtime performance, there are similar when used in constant expression, as all is done at compile time.
For compile time performance, issue of TMP is the number of instantiations whereas constexpr function (with regular parameter) generally use less instantiation, So TMP makes generally compilation longer.
But, in case memoization is required (as for Fibonacci with recursive implementation)
constexpr std::size_t fibonacci(std::size_t n)
{
if (n < 2) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
}
template <std::size_t N> struct Fibonacci
{
constexpr std::size_t value = Fibonacci<N - 2>::value + Fibonacci<N - 1>::value;
};
template <> struct Fibonacci<0>
{
constexpr std::size_t value = 1;
};
template <> struct Fibonacci<1>
{
constexpr std::size_t value = 1;
};
TMP should reuse instantiation whereas constexpr function might recompute it each time. In that case TMP will compile faster.
And why not replace TMP with constexpr if it is better?
First, we won't drop TMP which is used, for retro-compatibility.
Then, TMP is generally more adapted to return type or several types.
template <typename T> struct add_pointer
{
using type = T*;
};
using int_ptr = add_pointer<int>::type;
whereas constexpr would require decltype and/or std::declval
template <typename T> struct Tag { using type = T; };
constexpr Tag<T*> add_pointer(Tag<T>) {return {}; }
using int_ptr = decltype(add_pointer(Tag<int>{})::type;
constexprcoding isn't as capable as TMP at the moment. - Nicol Bolastuple_element_tto extract one of the types from atupletype. Pureconstexprcode can't do that; you can build aconstexprinterface to type computations, but the meat of the work is going to get shelled out to some form of TMP. - Nicol Bolasconstexpradvantage is mainly code readability and reduce compiler overhead in some cases (for ex. the typical compile time factorial would probably take less time to compile than recursive templates). Equivalent code should have similar performance and except if you have a serious performance problem, you should use whatever make the code easier to read. - Phil1970