返回模板函数的类型

Dan*_*Dan 6 c++ templates decltype c++11

信息:

我目前正在尝试学习模板元编程(通过阅读本书).他们给出的一个有用的例子是尺寸分析.我在书中实现了它,一切都很好; 看到这里.

然而,我的问题是,我想使用混合类型的维度分析框架.通过这个我的意思是你可以说一个标量的质量乘以一个矢量与加速度的维度,以给出一个矢量力.由于它位于链接中,因此它们仅对T所有操作的输入和输出使用相同类型.

我有一个3向量类,它具有所有必要的操作,用于乘以/除以标量等,所以我想做类似的事情

quantity<double,mass> m(1.0);
quantity<vect,acceleration> a(vect(0.0,0.0,-9.81));
quantity<vect,force> f = m*a;
Run Code Online (Sandbox Code Playgroud)

第一次尝试:

为了实现这一点,我尝试将书中的例子放到书中以处理两种不同的类型作为输入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());
}
Run Code Online (Sandbox Code Playgroud)

这里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());
}
Run Code Online (Sandbox Code Playgroud)

然而,这会引发许多难以理解的编译器错误.

题:

我的问题是,我decltype是以正确的方式使用但是缺少一些语法,例如typename某处的说明符?要么; 甚至可以这样做,如果不是这样,如何计算函数的返回类型?

谢谢.

Pie*_*BdR 6

好了,第一个类型return_type<T1,T2>::type是不是你仿佛在期待,但是是一个方法的类型,即T3 (return_type::*)(const T1&, const T2&)T3是你期望的类型.如果要使用中间类,可以使用:

template <typename T1, typename T2>
struct return_type
{
  typedef decltype(std::declval<T1>()*std::declval<T2>()) type;
};
Run Code Online (Sandbox Code Playgroud)

但您也可以直接使用decltype(T1()*T2())以获取产品类型.

编辑:我使用ildjarn的建议编辑了代码,因此不需要default-constructible类型.只是不要忘记包括<utility>

  • @Dan:请注意,本书是在C++ 11和`decltype` /`auto`可用性之前编写的,这使得事情变得更加复杂. (2认同)
  • 用`decltype(std :: declval <T1>()*std :: declval <T2>())`替换`decltype(T1()*T2())`,你不再需要默认的可构造性. (2认同)