【问题标题】:Conditional typedef of a function函数的条件类型定义
【发布时间】:2016-06-17 18:00:58
【问题描述】:

我正在尝试了解 boost mpl,我想知道这样的事情是否可行。具体来说,是否可以根据模板参数有条件地对函数进行类型定义?类似于这个玩具示例的内容:

template<typename arg1, typename arg2, typename rtype>
rtype getValue()
{
    typedef boost::conditional<
    // typedef boost::mpl::if_<
        boost::is_same<rtype, double>,
        double multiply(double a, double b),
        int multiply(int a, int b) 
    > function;
    function test;
    return test(arg1::value, arg2::value);
}

我尝试了上面的代码,得到了“模板参数2无效”的错误。所以我想知道是否有办法将函数定义转换为有效类型,因为它是有效的 typedef?

我也知道还有很多其他方法可以做到这一点。我不想解决问题,因为这是一种学习尝试。

【问题讨论】:

  • is_same后面不是少了一个逗号吗?
  • @lorro 我是,不幸的是我要编译的代码不是。

标签: c++ templates boost


【解决方案1】:

typedef 适用于 types 函数不是类型。

一个函数可能一个类型,例如,double multiply(double, double) 的类型是double (*)(double, double)。但是,类型实际上并没有链接到函数:double add(double, double) 与 double multiply(double, double) 具有相同的类型。

你可以做的是创建一个functor,它是一个可以像函数一样工作的类(一种类型)。

例如:

class DoubleMultiplier
{
public:
    double operator()(double value1, double value2) const
    {
        return value1 * value2;
    }
};

class IntMultiplier
{
public:
    int operator()(int value1, int value2) const
    {
        return value1 * value2;
    }
};

template<typename arg1, typename arg2, typename rtype>
rtype getValue()
{
    typedef boost::conditional<
    // typedef boost::mpl::if_<
        boost::is_same<rtype, double>,
        DoubleMultiplier,
        IntMultiplier 
    > function;
    function test;
    return test(arg1::value, arg2::value);
}

我假设您的具体示例是更复杂事物的简化版本。 DoubleMultiplier 和 IntMultiplier 做同样的事情,因此您可以创建一个模板化的 Multiplier - 当然您也可以直接在 getValue() 中将 arg1::value1 乘以 arg2::value2。

【讨论】:

    【解决方案2】:

    函数没有类型。您可以使用函数编写typedef,但这只是创建类型别名而不是函数类型。对于实际的函数,您可以使用函数指针作为模板参数创建模板,并以这种方式将函数转换为类型。例如

    template <typename T, T(*fun)(T, T)>
    struct arithmetic_fun {
        T operator(T x, T y) const { return fun(x, y); }
    };
    
    template <typename T>
    T multiply(T x, T y) {
        return x * y;
     };
    
    using int_multiply = arithmetic_fun<int, &multiply<int>>;
    // ...
    

    不过,使用这种方法有点不必要,因为标准 C++ 库无论如何都包含用于常见算术运算的类模板。当然,您可以使用这些来使所有这些元编程变得毫无意义:

       template <typename A1, typenam A2, typename R>
       R getValue() {
           using function = std::multiplies<R>;
           function test;
           return test(A1::value, A2::value);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 2014-09-20
      • 2023-02-10
      • 1970-01-01
      相关资源
      最近更新 更多