I believe it is exactly the same.
I would not say it is exactly the same.
In the first version, you are using a conditional statement which is evaluated at run-time, but the condition that decides which branch shall be executed can be (and is) decided at compile-time.
Therefore, both of your branches must compile and will be compiled no matter what the type of the input is, even though we known at compile-time that only one of them will be executed and the other will be dead - I expect the compiler would issue a warning here.
In the second case, you only compile (and execute, of course) what is appropriate for the type of the input. In my opinion, this makes the second approach superior.
Now even though in this particular situation it will likely make no difference which approach you choose, conditional executions that are decided by compile-time conditions should be expressed by means of compile-time constructs - SFINAE and template overloading, while if
should be used for conditions that depend on the run-time state of the system.
The first approach would not be possible, for instance, if the two branches of the conditional contained code that compiles only when the corresponding branch is executed. Consider these two types:
struct X
{
X(int) { }
};
struct Y
{
Y() { }
};
And the following function template:
template<typename T>
T foo(const T &a)
{
if (std::is_constructible<T, int>::value)
{
return T(42);
}
else
{
return T();
}
}
Now none of the following calls would be legal:
foo(X()); // ERROR! X is not default-constructible
foo(Y()); // ERROR! Y is not constructible from an int
This alone suggests that, in general, the appropriate tool for handling compile-time conditional execution is template overloading + SFINAE (or equivalent constructs possibly involving class template specializations).
Sure, there are degenerate cases (such as this one) that allow you using other tools, but if we are looking for conceptually correct design guidelines, I believe there is a clear winner here.
Things would of course be different if something like static if
existed in C++, but this is not the case at the moment - and not even in a near future, it seems.