[英]Return type of template function
Info: 信息:
I'm currently trying to learn template metaprogramming (by following this book ). 我目前正在尝试学习模板元编程(通过阅读本书 )。 One useful example they give is for dimensional analysis.
他们给出的一个有用的例子是尺寸分析。 I implemented it as in the book and everything was fine;
我在书中实现了它,一切都很好; see here .
看到这里 。
My problem is however, I want to use the dimensional analysis framework with mixed types. 然而,我的问题是,我想使用混合类型的维度分析框架。 By this I mean you could have say a scalar with dimensions of mass multiplying a vector with dimensions of acceleration to give a vector force.
通过这个我的意思是你可以说一个标量的质量乘以一个矢量与加速度的维度,以给出一个矢量力。 As it stands in the the link they only work with the same type
T
for input and output of all operations. 由于它位于链接中,因此它们仅使用相同类型
T
进行所有操作的输入和输出。
I have a 3-vector class which has all the necessary operations for multiplying with/dividing by scalars, etc. so I would like to do something like 我有一个3向量类,它具有所有必要的操作,用于乘以/除以标量等,所以我想做类似的事情
quantity<double,mass> m(1.0);
quantity<vect,acceleration> a(vect(0.0,0.0,-9.81));
quantity<vect,force> f = m*a;
First attempt: 第一次尝试:
To acheive this I tried exending the examples form the book to handle two different types as inputs to operator*
and operator/
however I hit a wall when it comes to the return type. 为了实现这一点,我尝试将书中的示例放到处理两个不同类型作为
operator*
和operator/
输入,但是当涉及到返回类型时,我碰到了一个墙。
I know here the return type of double * vect
is vect
but if they are the other way around vect * double
it is still a vect
. 我知道
double * vect
的返回类型是vect
但是如果它们是另一种方式vect * double
它仍然是一个vect
。 Worse; 更差; in principle the return type could be anything.
原则上,返回类型可以是任何东西。 So I want a way to extend the
operator*
to something like 所以我想要一种方法将
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());
}
where X
is the return type of q1.value()*q2.value()
and is deduced at compile time. 其中
X
是q1.value()*q2.value()
的返回类型,并在编译时推导出。 I tried simply adding another template class T3
to the signature and having it return T3
but it seems it cannot deduce what T3
should be. 我尝试简单地在签名中添加另一个模板类
T3
并让它返回T3
但似乎无法推断T3
应该是什么。
Second attempt: 第二次尝试:
Next I tried using decltype
as follows 接下来我尝试使用
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());
}
However this throws a multitude of incomprehensible compiler errors. 然而,这会引发许多难以理解的编译器错误。
Question: 题:
My question is then, am I using decltype
in the correct way but missing some syntax eg a typename
specifier somewhere? 我的问题是,我是否以正确的方式使用
decltype
但是缺少一些语法,例如某处的typename
说明符? Or; 要么; is it even possible to do this this way and if not how is it possible to compute the return type of a function?
甚至可以这样做,如果不是这样,如何计算函数的返回类型?
Thanks. 谢谢。
Ok, so first the type return_type<T1,T2>::type
is not what you seem to be expecting but is the type of a method, namely T3 (return_type::*)(const T1&, const T2&)
with T3
being the type you are expecting. 好的,所以首先类型
return_type<T1,T2>::type
不是你想象的那样但是是方法的类型,即T3 (return_type::*)(const T1&, const T2&)
其中T3
是你期待的类型。 If you want to use an intermediate class, you can use: 如果要使用中间类,可以使用:
template <typename T1, typename T2>
struct return_type
{
typedef decltype(std::declval<T1>()*std::declval<T2>()) type;
};
But you could also use directly decltype(T1()*T2())
to get the type of the product. 但您也可以直接使用
decltype(T1()*T2())
来获取产品的类型。
Edit : I edited the code with the suggestion of ildjarn, so no need for default-constructible types. 编辑 :我使用ildjarn的建议编辑了代码,因此不需要default-constructible类型。 Just don't forget to include
<utility>
只是不要忘记包含
<utility>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.