Since r is known at instantiation time, it seems incorrect to execute the if at runtime. This should be a decision to be made at compile time. How can I accomplish this?
std::enable_if relies on SFINAE; on discarding functions from the overload resolution set if there is a substitution failure when a deduced type is substituted for a template parameter.
In this particular case, there is no type deduction; the only argument is known to be of type long double. For SFINAE to come into play, we would have to forward the call to a helper function which takes an extra argument, for which the type is deduced.
Just one detail: in your first solution, we have to create an object (r{}), so I don't think its more efficient than a runtime if as in my first approach (being Very Picky here!):
Tag dispatch also creates an object (the object is the tag).
Tough in both cases, the as-if rule would permit optimising away the creation of the object.
(You can verify that in both cases, if the argument is a constexpr, the function is evaluated at compile-time.)
But yes; in general, code involving tag dispatch tends to be cleaner than techniques using SFINAE.
The original code (with the if) does not involve creation of any secondary object.
To force compile time evaluation, all we need to do is change that to an arithmetic if and remove modifications of objects in the evaluation.