如何在模板中推导出C ++返回类型?

时间:2016-04-15 10:02:07

标签: c++ templates functor generic-programming c++03

我有一个仿函数,我希望自动推导出返回类型。我怎么能这样做?

template <typename _ScalarL, typename _ScalarR>
struct Multi
{
    DEDUCEDTYPE operator()(_ScalarL input1, _ScalarR input2) const
    {
        return input1 * input2;
    }
};

int main(){
    Multi<int, double> mt;
    mt(1,2.0);
}

如何自动获取DEDUCEDTYPE

2 个答案:

答案 0 :(得分:3)

我相信在c ++ 11之前你注定要手工提供演绎......你可以创建一个带有特殊化的辅助结构:

template <typename A, typename B>
struct deduce { };

template <>
struct deduce<int, double> {
   typedef double type;
};

template <typename ScalarL, typename ScalarR>
struct Multi
{
    typename deduce<ScalarL, ScalarR>::type operator()(ScalarL input1, ScalarR input2) const
    {
        return input1 * input2;
    }
};

int main(){
    Multi<int, double> mt;
    mt(1,2.0);
}

修改

执行此操作的更一般方法将调用创建在推导结果类型时应考虑的类型的优先级层次结构。示例代码:

#include <iostream>

template <typename T>
struct MoreGeneralNumber { };

template <>
struct MoreGeneralNumber<long>: MoreGeneralNumber<int> {};

template <>
struct MoreGeneralNumber<float>: MoreGeneralNumber<long> {};

template <>
struct MoreGeneralNumber<double>: MoreGeneralNumber<float> {};

typedef char (&yes)[1];
typedef char (&no)[2];

template <bool L, bool R, typename LT, typename RT>
struct MoreGeneral { };

template <bool R, typename LT, typename RT>
struct MoreGeneral<true, R, LT, RT> {
   typedef LT type;
};

template <typename LT, typename RT>
struct MoreGeneral<false, true, LT, RT> {
   typedef RT type;
};

template <typename B, typename D>
struct Host
{
  operator B*() const;
  operator D*();
};

template <typename B, typename D>
struct is_base_of
{
  template <typename T> 
  static yes check(D*, T);
  static no check(B*, int);

  static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);
};

template <typename L, typename R>
struct Deduce: MoreGeneral<is_base_of<MoreGeneralNumber<R>, MoreGeneralNumber<L> >::value, 
                           is_base_of<MoreGeneralNumber<L>, MoreGeneralNumber<R> >::value, L, R >  {
};

template <typename ScalarL, typename ScalarR>
struct Multi
{
    typename Deduce<ScalarL, ScalarR>::type operator()(ScalarL input1, ScalarR input2) const
    {
        return input1 * input2;
    }
};

int main() {
   Multi<int, double> mt;
   std::cout << mt(1, 2.5) << std::endl; 
}

答案 1 :(得分:3)

  

如何自动获取DEDUCEDTYPE [与c ++ 03]?

使用C ++ 03 无法实现自动类型扣除。如其他答案中所述,您可能必须手动创建自己的演绎特化。

C ++ 11 / C ++ 14

// For C++14, simply `auto` is enough
auto operator()(_ScalarL input1, _ScalarR input2) const
#if __cplusplus < 201402L
-> decltype(input1 * input2) // required for C++11
#endif