我正在尝试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){ …Run Code Online (Sandbox Code Playgroud) 亲爱的Assembly/C++ dev,
问题是:传播两个ASM块之间的进位(或任何标志)是现实的还是完全疯狂的,即使它有效?
几年前,我为低于512位的大型算术开发了一个整数库(在编译时).我此时没有使用GMP,因为对于这种规模,GMP由于内存分配而变慢,并且模型选择二进制表示工作台.
我必须承认我创建了我的ASM(字符串块)使用BOOST_PP,它不是非常光荣(好奇的看看它vli).图书馆运作良好.
但是我注意到,此时不可能在两个ASM内联块之间传播状态寄存器的进位标志.这是合乎逻辑的,因为对于编译器在两个块之间生成的任何助记符,寄存器被复位(mov指令除外(来自我的汇编知识)).
昨天我有一个想法,传播两个ASM块之间的进位有点棘手(使用递归算法).它工作,但我认为我很幸运.
#include <iostream>
#include <array>
#include <cassert>
#include <algorithm>
//forward declaration
template<std::size_t NumBits>
struct integer;
//helper using object function, partial specialization is forbiden on functions
template <std::size_t NumBits, std::size_t W, bool K = W == integer<NumBits>::numwords>
struct helper {
static inline void add(integer<NumBits> &a, const integer<NumBits> &b){
helper<NumBits, integer<NumBits>::numwords>::add(a,b);
}
};
// first addition (call first)
template<std::size_t NumBits, std::size_t W>
struct helper<NumBits, W, 1> {
static …Run Code Online (Sandbox Code Playgroud) 我对模板有一个奇怪的问题,我试图在模板类和"float/double/int"类型之间进行基本的添加.这是非常基本的,但如果我这样做:
template<class T>
class toto{
T a;
};
template<class T>
toto<T> operator+(toto<T> const&, T&){
std::cout << "hello " <<std::endl;
}
int main(){
toto<float> t;
toto<float> d = t +2.3;
}
Run Code Online (Sandbox Code Playgroud)
它不会编译,因为2.3被认为是双精度,它与签名不匹配.我可以为我的operator +使用第二个模板参数
template<class T, class D>
toto<T> operator+(toto<T> const&, D&){
std::cout << "hello " <<std::endl;
}
Run Code Online (Sandbox Code Playgroud)
它编译,正确执行,但太危险D可以是一切.另一种方法是使用float,double或int(O_O)创建不同的签名.Boost :: enable_if似乎是我的解决方案,但在我阅读的文档中:
template <class T>
T foo(T t,typename enable_if<boost::is_arithmetic<T> >::type* dummy = 0);
Run Code Online (Sandbox Code Playgroud)
将此方法应用于operator*doest不起作用,因为编译器抱怨默认参数是被禁止的.
有什么建议 ?
干杯,
++Ť