constexpr против шаблона, функция pow

Я экспериментирую с новой функцией c ++ 11, особенно с constexpr.
Если я захочу написать код с помощью шаблона, я просто сделаю:

//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?
Лучший.

10

Решение

inline — не более чем подсказка для компилятора. Он может делать все, что захочет. Он содержит специфичные для компилятора вещи, такие как прагмы и __declspec, чтобы принудительно включать или выключать встраивание в функцию.

Может быть неконстантной ссылкой на версию constexpr. Вы все равно должны просто передать значение по пау.

1

Другие решения

Не является ошибкой то, что конкретное создание шаблона функции constexpr не является по-настоящему constexpr, если вы не пытаетесь использовать его в контексте, требующем постоянного выражения. Возможно, ваш созданный шаблон не является constexpr.

Чтобы узнать, сделайте это:

constexpr double powtest = pow(2.0, 5);

Если компилятор жалуется, вы знаете, что что-то не так.

1

По вопросам рекламы [email protected]