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

标签 c++ templates functional-programming

我有一个类似 vector 的类,其中包含 "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];
};

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

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];
};

现在,问题是,如何将采用两个内部类型并返回 void 的运算符传递给 do_for_each,如上例所示? C++ 不允许我对内部类型执行此技巧("T::operator+=" 如果 "T""int" 将不起作用>).

最佳答案

首先,您应该真正从您的 operator+= 返回一个引用,因为您稍后可以使用它们来实现 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];
};

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

关于C++:使用两种内在类型的运算符作为函数对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/293421/

相关文章:

javascript - reducer 组合 - 为什么我们需要使用 Object.assign() 重新分配待办事项,为什么不直接调用另一个 reducer 呢?

scala - 在 Scala 中仅使用 foldRight、foldLeft 和 unfold 实现 map 功能

c++ - Windows 平台最快的 C++ 链接器是什么?

c++ - 局部变量的引用崩溃

c++ - 在 C++ 中使用别名而不改变原始变量的值?

c++ - STL 映射是否在插入时初始化原始类型?

c++ - 在实例化派生类时指定基类模板参数?

c++ - 返回对原始参数的引用

python - 如何在 Flask 的扩展名为 .jhtml 的模板中启用自动转义?

r - 如何在 R 中连接/组合函数?