信息:
我目前正在尝试学习模板元编程(通过遵循这本书)。他们给出的一个有用的例子是维度分析。我按照书中的方式实现了它,一切都很好;看这里。
然而,我的问题是,我想使用混合类型的维度分析框架。我的意思是你可以说一个具有质量维度的标量乘以一个向量与加速度的维度来给出一个向量力。正如链接中所示,它们仅适用于T
所有操作的输入和输出的相同类型。
我有一个 3-vector 类,它具有所有必要的操作,用于乘以/除以标量等,所以我想做类似的事情
quantity<double,mass> m(1.0);
quantity<vect,acceleration> a(vect(0.0,0.0,-9.81));
quantity<vect,force> f = m*a;
第一次尝试:
为了实现这一点,我尝试扩展书中的示例来处理两种不同的类型作为输入operator*
,operator/
但是在返回类型方面我碰壁了。
我知道这里的返回类型double * vect
是,vect
但如果它们是相反的,vect * double
它仍然是vect
. 更差; 原则上返回类型可以是任何东西。所以我想要一种方法将其扩展operator*
到类似的东西
template<class T1, class T2, class Dim1, class Dim2>
quantity<X, typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
operator*(const quantity<T1,Dim1>& q1, const quantity<T2,Dim2>& q2)
{
return quantity<X,
typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
(q1.value()*q2.value());
}
哪里X
是返回类型q1.value()*q2.value()
并且是在编译时推导出来的。我尝试简单地将另一个模板类添加T3
到签名中并让它返回T3
,但它似乎无法推断出T3
应该是什么。
第二次尝试:
接下来我尝试使用decltype
如下
template<class T1, class T2>
struct return_type
{
auto mult_f(const T1& a, const T2& b)->decltype(a*b){return a*b;}
typedef decltype(mult_f) type;
};
template<class T1, class T2, class Dim1, class Dim2>
quantity<typename return_type<T1,T2>::type, typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
operator*(const quantity<T1,Dim1>& q1, const quantity<T2,Dim2>& q2)
{
return quantity<typename return_type<T1,T2>::type,
typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
(q1.value()*q2.value());
}
然而,这会引发大量难以理解的编译器错误。
问题:
那么我的问题是,我是否decltype
以正确的方式使用但缺少一些语法,例如typename
某处的说明符?或者; 甚至可以这样做吗?如果不是,如何计算函数的返回类型?
谢谢。