我知道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的情况下。
答案 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
(如果T
是float
或double
) ,或完全删除它(否则)。这是一个相当基本的优化。
答案 2 :(得分:0)
您需要确保T
float
或double
的所有代码路径和其他代码路径需要同时有效才能进行编译。如果if
和else
中的代码对特定类型无效,则会遇到错误。
对于应用的确切优化,您需要检查汇编代码。