我有一个类似 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/