c++更通用的运算符模板
所以我刚刚学习了(谢谢大家)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;
}
是否有可能使这种模板更加“元”,因为我们允许运算符(“*”)本身作为模板参数?即,有一个适用于 *、+、% 等的模板定义,其中在 *c = (*a) op (*b) 中使用适当的运算符 op ?
我打赌不是,但那就太好了!
So I just learned (thanks guys) about decltype. I now can write really nice vector templates that actually outperform 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;
}
Is it possible to make this kind of templating even more "meta", in the sense that we allow the operator ("*") itself to be a template parameter? I.e. have one single template definition that works for *, +, %, etc, where the appropriate operator op is used in *c = (*a) op (*b)?
I'm betting it is not, but it would be nice!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如您所预料的,答案是“不”。 :)
但是,您可以使用预处理器来生成此类函数:
As you expected, this answer is "no." :)
However, you can use the preprocessor to generate such functions:
使用 std::declval() 而不仅仅是
T()
,它可能没有默认构造函数(因为 std::vector 没有需要一个默认构造函数,仅需要一个复制构造函数)。另外,请非常确定类型和内容。参考与右值引用的正确性和转发,类可能会以不同的方式实现值、引用、const 引用、右值引用。用几个类来测试它。另外,请注意,由于未实现的功能,返回类型提取可能不适用于 GCC 中的复合赋值运算符。
是的,我用指针包装类中的参数化宏解决了这个问题:http://frigocoder。 dyndns.org/code/Frigo/Lang/ref
例如
Use
std::declval<T&&>()
instead of justT()
, it might not have a default constructor (since std::vector does not require a default constructor, only a copy constructor). Also, be very sure about type & reference & rvalue reference correctness and forwarding, classes may implement things differently for values, references, const references, rvalue references. Test it with several classes.Also, mind you that the return type extraction might not work for compound assignment operators in GCC due to an unimplemented feature.
And yes, I solved it with parameterized macros in my pointer wrapper class: http://frigocoder.dyndns.org/code/Frigo/Lang/ref
For example