我正在尝试c ++ 11的新功能,特别是constexpr。 如果我想用模板对pow进行编码,我只会这样做:
//pow
template<class T, std::size_t n>
struct helper_pow{
inline static T pow(T const& a){
return a*helper_pow<T,n-1>::pow(a);
}
};
//final specialization pow
template<class T>
struct helper_pow<T,0>{
inline static T pow(T const& a){
return 1;
}
};
现在,如果我只是通过以下方式将我的函数调用到我的代码中:
pow<double,5>(a) // where a is double
相应的程序集将是(gcc 4.8.0,-O2):
movapd %xmm0, %xmm1
movsd %xmm0, 24(%rsp)
mulsd %xmm0, %xmm1
movq %rbx, %rdi
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm1
精细的代码是内联的。
如果知道我正在查看constexpr版本,我有
template <class T>
inline constexpr T pow(T const& x, std::size_t n){
return n>0 ? x*pow(x,n-1):1;
}
现在是相应的程序集:
movsd 24(%rsp), %xmm2
leaq 24(%rsp), %rdi
movl $4, %esi
movsd %xmm2, 8(%rsp)
call __Z3powIdET_RS0_m
函数__Z#powIdET_RS0_m似乎由
定义LCFI1:
mulsd %xmm1, %xmm0
movapd %xmm0, %xmm2
mulsd %xmm1, %xmm2
mulsd %xmm2, %xmm1
movapd %xmm1, %xmm0
ret
那你有没有想过为什么使用constexpr这个函数不是内联的并且被认为是“外部”函数?是否存在强制constexpr函数内联的方法? 最好的。
答案 0 :(得分:1)
inline只不过是编译器的提示。它可以做任何它喜欢的事情。它存在编译器特定的东西,如pragma和__declspec,用于强制打开或关闭函数的内联。
可能是constexpr版本干扰的非const值左侧参考。无论如何,你应该通过值传递给一个战俘。
答案 1 :(得分:1)
constexpr函数模板的特定实例化不是真正的constexpr,这不是错误,只要您不尝试在需要常量表达式的上下文中使用它。也许你的实例化模板不是constexpr。
要找到答案,请执行以下操作:
constexpr double powtest = pow(2.0, 5);
如果编译器抱怨,你知道有什么问题。