我试图了解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);
}
我尝试了上面的代码并得到错误&#34;模板参数2无效&#34;。所以我想知道是否有办法将函数定义转换为有效类型,因为它是一个有效的typedef?
我也知道还有很多其他方法可以做到这一点。我不想要一个解决方法,因为这是一个学习的尝试。
答案 0 :(得分:2)
typedef适用于类型函数不是类型。
函数可能具有类型,例如,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做同样的事情,所以你可以做一个模板化的乘数 - 当然你也可以直接在arg2 :: value2乘以getValue()。
答案 1 :(得分:1)
功能不是类型。您可以使用函数编写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);
}