【问题标题】:Return type of template function模板函数的返回类型
【发布时间】:2012-06-21 07:21:45
【问题描述】:

信息:

我目前正在尝试学习模板元编程(关注this book)。他们给出的一个有用的例子是维度分析。我按照书中的方式实现了它,一切都很好; see here.

然而,我的问题是,我想使用混合类型的维度分析框架。我的意思是你可以说一个具有质量维度的标量乘以一个向量与加速度的维度来给出一个向量力。正如链接中所示,它们仅适用于相同类型的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());
}

其中Xq1.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 某处的说明符?要么;甚至可以这样做吗?如果不是,如何计算函数的返回类型?

谢谢。

【问题讨论】:

    标签: c++ templates c++11 decltype


    【解决方案1】:

    好的,所以首先return_type&lt;T1,T2&gt;::type 类型不是您所期望的,而是方法的类型,即T3 (return_type::*)(const T1&amp;, const T2&amp;)T3 是您所期望的类型。如果要使用中间类,可以使用:

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

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

    编辑:我根据 ildjarn 的建议编辑了代码,因此不需要默认可构造类型。只是不要忘记包含&lt;utility&gt;

    【讨论】:

    • 是的,我可以从编译器输出中看出我正在获取整个函数签名。我不知道为什么我让事情变得如此复杂,你的例子编译得很好:) 默认构造函数要求对我来说不是问题。
    • @Dan:请注意,这本书是在 C++11 和 decltype / auto 可用性之前编写的,这使得事情非常变得更加复杂。
    • decltype(T1()*T2()) 替换为decltype(std::declval&lt;T1&gt;()*std::declval&lt;T2&gt;()),您不再需要默认的可构造性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多