简体   繁体   English

返回模板函数的类型

[英]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. 其中Xq1.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM