C++:使用两个内部类型的运算符作为函数对象

Ale*_*x B 5 c++ templates functional-programming

我有一个类似于矢量的类,它包含一个类型的对象数组"T",我想实现4个算术运算符,它们将对每个项应用操作:

// Constructors and other functions are omitted for brevity.
template<class T, unsigned int D>
class Vector {

public:
    // Add a value to each item: naive implementation.
    void operator += (const T&) {
        for (int i = 0; i < D; ++i) {
            data[i] += value;
        }
    }
    void operator -= (const T&) { ... }
    void operator *= (const T&) { ... }
    void operator /= (const T&) { ... }

private:
    T items[D];
};
Run Code Online (Sandbox Code Playgroud)

因为运算符将包含相同的样板代码(遍历每个元素并应用适当的操作),我想我可以概括它:

template<class T, unsigned int D>
class Vector {

public:
    void operator += (const T& value) { do_for_each(???, value); }
    void operator -= (const T& value) { do_for_each(???, value); }
    void operator *= (const T& value) { do_for_each(???, value); }
    void operator /= (const T& value) { do_for_each(???, value); }

private:
    void
    do_for_each(std::binary_function<void, T, T>& op, T value) {
        std::for_each(data, data + D, std::bind2nd(op, value));
    }

    T data[D];
};
Run Code Online (Sandbox Code Playgroud)

现在的问题是,我如何通过运营商,它有两个固有的类型,并返回voiddo_for_each在上面的例子中所描述的,?C++不允许我为内在类型做这个技巧("T::operator+="如果"T"是的话就行不通"int").

Joh*_*itb 8

首先,您应该从运算符+ =返回一个引用,因为您以后可以使用它们来实现operator +,operator-等等.我会相应地改变它.

此外,您的do_for_each必须是一个模板,因为它必须知道函数对象的精确类型,因为二进制函数对象不是多态类.对于实际操作,您要使用std::transform:

template<class T, unsigned int D>
class Vector {

public:
    Vector& operator += (const T& value) { 
        do_for_each(std::plus<T>(), value); 
        return *this;
    }

    Vector& operator -= (const T& value) { 
        do_for_each(std::minus<T>(), value); 
        return *this;
    }

    Vector& operator *= (const T& value) { 
        do_for_each(std::multiplies<T>(), value);
        return *this; 
    }

    Vector& operator /= (const T& value) { 
        do_for_each(std::divides<T>(), value); 
        return *this;
    }

private:
    template<typename BinFun>
    void do_for_each(BinFun op, const T& value) {
        std::transform(data, data + D, data, std::bind2nd(op, value));
    }

    T data[D];
};
Run Code Online (Sandbox Code Playgroud)

std :: transform只是将每个元素传递给函数对象,并将结果返回给作为第三个参数给出的迭代器.