Search code examples
c++c++11compile-time

Can this condition using std::is_same<> be evaluated at compile time?


I know that constexpr functions don't have to be evaluated at compile time, but they are if it is possible. Is the condition of the following if evaluated at compile time or not?

template <typename T> inline std::string toString(const T& arg, int decPlaces) 
{ 
    if (!std::is_same<T, float>::value && !std::is_same<T, double>::value)
        return std::to_string(arg);
    // Else go on strip digits after decimal point
}

I know that in C++17 there is if constexpr which guarantees evaluation at compile time, but I'm just wondering whether it might be evaluated at compile time in this case because the bool returned from is_same is constexpr. Such as in a situation when C++17 cannot be used.


Solution

  • Consider this slightly modified version of your code (so that the control flow cannot reach the end of such a non-void function):

    template <typename T> inline std::string toString(const T& arg, int decPlaces) 
    { 
        if (!std::is_same<T, float>::value && !std::is_same<T, double>::value)
            return std::to_string(arg);
    
        return ""; // <-- added
    }
    

    By explicitly instantiating your template function for T=float:

    template std::string toString<float>(const float&, int);
    

    and then compiling it with g++ 6.4.0 and -O2 enabled, the following assembly code is generated for the x86 platform:

    __Z8toStringIfESsRKT_i:
        pushl   %ebx
        subl    $40, %esp
        movl    48(%esp), %ebx
        leal    31(%esp), %eax
        movl    $LC0, 4(%esp)
        movl    %eax, 8(%esp)
        movl    %ebx, (%esp)
        call    __ZNSsC1EPKcRKSaIcE
        addl    $40, %esp
        movl    %ebx, %eax
        popl    %ebx
        ret $4
    

    There is nothing conditional in the code above.

    So, for this compiler and platform, the condition is actually evaluated at compile time. You can proceed analogously for your targeted compiler and platform.