【发布时间】:2011-09-26 12:44:02
【问题描述】:
所以我刚刚学习了(谢谢大家)关于 decltype 的知识。我现在可以编写非常好的矢量模板,实际上优于 valarrays(!):
template <typename T, typename U>
vector<decltype(T()*U())> operator*(const vector<T>& A, const vector<U>& B){
vector<decltype(T()*U())> C = vector<decltype(T()*U())>(A.size());
typename vector<T>::const_iterator a = A.begin();
typename vector<U>::const_iterator b = B.begin();
typename vector<decltype(T()*U())>::iterator c = C.begin();
while (a!=A.end()){
*c = (*a) + (*b);
a++; b++; c++;
}
return C;
}
在我们允许运算符(“*”)本身作为模板参数的意义上,是否有可能使这种模板更加“元”? IE。有一个适用于 *、+、% 等的模板定义,其中在 *c = (*a) op (*b) 中使用了适当的运算符 op?
我打赌它不是,但它会很好!
【问题讨论】:
-
这本质上是
accumulate的二进制版本,尽管accumulate本身已经可以用于类似的东西,虽然不是那么对称。不过,真正的力量可能来自惰性评估包装器。 -
... 吹毛求疵:您可能希望对
C和reserve使用默认构造以确保它不需要增长,然后使用push_back(而不是创建数组的大小 --awkwardly 与vector<x> c = vector<x>( a.size() )-- 并重写元素)。使用类型定义!它们有助于提高可读性,单个typedef decltype( A.front()*B.front() ) result_type将使代码更具可读性。避免向泛型代码添加不必要的要求(当前实现使用T()、U()和result_type()强加了默认构造函数的存在) -
@DavidRodríguez-dribeas:我发现使用 push_back 比完整的声明/重写版本慢得多,在我的测试用例中慢了 50%。
-
@KerrekSB:我将不得不检查惰性评估包装器,我对它们一无所知。
-
@andyInCambridge:您执行测试的设置是什么?您是否提前预订空间?请注意,
reserve()调用将产生巨大的影响,因为它将确保发生单个内存分配(假设您保留了适当的大小),在这种情况下,它应该比您的方法更快。如果不是,我很想知道您正在运行什么编译器、平台和测试...