constexpr与模板,pow功能

Tim*_*afé 10 c++ templates c++11 gcc4.8

我正在尝试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;
    }
};
Run Code Online (Sandbox Code Playgroud)

现在,如果我将我的函数调用到我的代码中,只需:

pow<double,5>(a) // where a is double
Run Code Online (Sandbox Code Playgroud)

相应的程序集将是(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
Run Code Online (Sandbox Code Playgroud)

精细的代码是内联的.

如果知道我正在寻找constexpr版本,我有

template <class T>
inline constexpr T pow(T const& x, std::size_t n){
    return n>0 ? x*pow(x,n-1):1;
} 
Run Code Online (Sandbox Code Playgroud)

相应的程序集现在是:

    movsd   24(%rsp), %xmm2
    leaq    24(%rsp), %rdi
    movl    $4, %esi
    movsd   %xmm2, 8(%rsp)
    call    __Z3powIdET_RS0_m
Run Code Online (Sandbox Code Playgroud)

其中函数__Z#powIdET_RS0_m似乎由.定义

LCFI1:
    mulsd   %xmm1, %xmm0
    movapd  %xmm0, %xmm2
    mulsd   %xmm1, %xmm2
    mulsd   %xmm2, %xmm1
    movapd  %xmm1, %xmm0
    ret
Run Code Online (Sandbox Code Playgroud)

所以你有任何想法为什么使用constexpr函数不是内联函数并被视为"外部"函数?是否存在强制constexpr函数内联的方法?最好.

gal*_*p1n 1

inline只不过是给编译器的一个提示。它可以做任何它喜欢做的事情。它存在编译器特定的东西,如编译指示和 __declspec 来强制打开或关闭函数的内联。

可能是 constexpr 版本的非 const 左值引用造成干扰。无论如何,你应该将值传递给 pow。