这种情况可以使用std :: is_same<>在编译时进行评估?

时间:2018-02-13 08:18:49

标签: c++ c++11 compile-time

我知道constexpr函数不必在编译时进行评估,但如果可能的话,它们就是它们。是否在编译时评估了以下if的条件?

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
}

我知道在C ++ 17中有if constexpr可以保证在编译时进行评估,但我只是想知道在这种情况下是否可以在编译时对其进行评估,因为bool已返回来自is_same的{​​{1}}。例如在不能使用C ++ 17的情况下。

3 个答案:

答案 0 :(得分:2)

考虑这个稍微修改过的代码版本(以便控制流程无法到达这种非void函数的末尾):

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
}

通过显式实例化T=float的模板函数:

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

然后在启用g++ 6.4.0 -O2的情况下编译它,为 x86 平台生成以下汇编代码:< / p>

__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

上面的代码中没有条件

因此,对于此编译器和平台,实际上在编译时评估条件。您可以类似地针对目标编译器和平台进行操作。

答案 1 :(得分:0)

如果您想确定,请检查生成的装配体。但是,编译器确实可以用无条件的if替换return(如果Tfloatdouble) ,或完全删除它(否则)。这是一个相当基本的优化。

答案 2 :(得分:0)

您需要确保T floatdouble的所有代码路径和其他代码路径需要同时有效才能进行编译。如果ifelse中的代码对特定类型无效,则会遇到错误。

对于应用的确切优化,您需要检查汇编代码。