如何将算术运算符传递给模板?

Old*_*der 4 c++ templates operators

我想以某种方式将这些模板合并为一个:

template <class Result, class T1, class T2>
class StupidAdd
{
public:
    T1 _a; T2 _b;
    StupidAdd(T1 a, T2 b):_a(a),_b(b) {}
    Result operator()() { return _a+_b; }
};

template <class Result, class T1, class T2>
class StupidSub
{
public:
    T1 _a; T2 _b;
    StupidSub(T1 a, T2 b):_a(a),_b(b) {}
    Result operator()() { return _a-_b; }
};
Run Code Online (Sandbox Code Playgroud)

(其次是Mul,Div等相同的代码),其中所有代码都是相同的,除了实际的"+"," - "(和"StupidAdd","StupidSub"等).

然后,这些愚蠢的"仿函数"被另一个模板使用.如何在没有预处理器的情况下避免重复?(我进入模板的原因是为了避免预处理器)

也就是说,如何将算术运算符传递给模板?

Luc*_*lle 7

也许你可以使用std::plus<T>,std::minus<T>,std::multiplies<T>std::divides<T>.但是,只有当两个操作数属于同一类型时,或者如果左侧操作数可以转换为第一个类型,它们才有效.

除了使用预处理器之外,我没有看到任何方法来实现您要做的事情.不想要宏的任何好理由?

如果你想确保返回类型足够大以包含结果,你可以这样做:

#include <functional>
#include <boost/mpl/if_.hpp>

// Metafunction returning the largest type between T and U
// Might already exist in Boost but I can't find it right now...maybe 
// boost::math::tools::promote_args
template <typename T, typename U>
struct largest :
    boost::mpl::if_<
        boost::mpl::bool_<(sizeof(T) > sizeof(U))>,
        T,
        U
    >
{};

template <typename T, typename U, template <typename S> class Op>
struct Foo
{
    typedef typename largest<T, U>::type largeType;

    largeType bar(const T & t, const U & u)
    {
        return Op<largeType>()(t, u); // Applies operator+
    }
};

int main()
{
    Foo<int, double, std::plus> f;
    double d = f.bar(12, 13.0); // takes int and double, returns double
}
Run Code Online (Sandbox Code Playgroud)

在这里,我使用Boost MPL来编写largest元函数,但if如果你不能使用Boost(由两种类型参数化的类模板和一个专门用于true和false的bool),你可以编写自己的元函数.

要确定表达式的返回类型,您还可以查看boost :: result_of,如果我理解正确的话,它等同decltype于C++ 0x中即将出现的运算符.