C++ choose between runtime and compile time implementation functions I wrote a small wrapper function to choose between runtime (std) sqrt and a constexpr version, as a continuation of the vector class I published here earlier:

C++ mathematical n-dimensional vector template using fold expressions

It seems to work fine and Compiler Explorer shows that the sqrt function is completely compiled out.

The relevant code (sqrt coming from the standard library):

constexpr T cx_sqrt(const T&amp; m) const {
    int i = 0;
    while((i*i) &lt;= m) {
        i++;
    }
    i--;
    T d = m - (i * i);
    T p = d / (2 * i);
    T a = i + p;
    return a - (p * p) / (2 * a);
}

constexpr T choose_sqrt(const T&amp; m) const {
    return (__builtin_constant_p(m) &amp;&amp; __builtin_constant_p(*m)) ?  cx_sqrt(m) : sqrt(m);
}

template &lt;size_t... I&gt;
constexpr T magnitude_impl(std::index_sequence&lt;I...&gt;) const {
    return choose_sqrt(((values[I] * values[I]) + ...));
}


Any gotchas using a method like this?
As of C++20, you can use std::is_constant_evaluated(), which is more portable and considerably easier to read.  I realize you have only tagged C++17, but I just wanted to point out that there is now a cleaner solution to this problem.
#include &lt;type_traits&gt;
#include &lt;cmath&gt;

namespace example
{
    namespace impl
    {
        template&lt;typename T&gt;
        constexpr auto sqrt(const T&amp; m) noexcept -&gt; decltype(std::sqrt(m)) {
            // implementation details
        }
    }

    template&lt;typename T&gt;
    constexpr auto sqrt(const T&amp; m) noexcept {
        if (std::is_constant_evaluated())
            return impl::sqrt(m);
        else
            return std::sqrt(m);
    }
}