我想创建一个函数,让vector<int>
遍历所有元素,并根据我选择的特定运算符“求和”它们。
例如,v1 = [3,6,7]
所以我可以通过此函数计算3+6+7
3-6-7
的{{1}}等。
为此我做了 -
3*6*7
在这种模板的情况下,我不能很好地控制,因为你可以看到这段代码不起作用,但我想你明白我的目标是什么。如何修复它才能正常工作?
修改
根据我得到的2个答案,我将代码部分更改为 -
#include <iostream>
#include <vector>
using namespace std;
#define OPERATOR(X,Y,OP) X #OP Y
template<T>
int allVectorWithOperator(vector<int> &myVector, T) {
vector<int>::iterator it;
vector<int>::iterator oneBeforeFinal;
oneBeforeFinal = myVector.end();
oneBeforeFinal -= 2;
int sum = 0;
for (it = myVector.begin(); it <= oneBeforeFinal; it++) {
sum = OPERATOR(*(it),*(it+1),T);
}
return sum;
}
int main() {
vector<int> myVector;
myVector.push_back(3);
myVector.push_back(6);
myVector.push_back(7);
cout << "run over all the vector with * is :" << allVectorWithOperator(myVector,*)<<endl;
// here I want to get 3*6*7
}
它工作正常!确实是我#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
template<typename T>
int allVectorWhitOperator(vector<int> &myVector, const T& func) {
int sum = std::accumulate(myVector.begin(), myVector.end(), 1, func);
return sum;
}
int main() {
vector<int> myVector;
myVector.push_back(3);
myVector.push_back(4);
myVector.push_back(6);
cout << "accumulate the vector with * is :"
<< allVectorWhitOperator(myVector, std::multiplies<int>()) << endl;
}
答案 0 :(得分:7)
标准库已经在 <algorithm>
<numeric>
中进行了操作。
您可以使用
int sum = std::accumulate(MyVector.begin(), MyVector.end(), 0);
添加所有元素。
如果您想计算产品(而不是使用默认的operator+
),您可以传递一个额外的参数
int product = std::accumulate(MyVector.begin(), MyVector.end(), 1,
std::multiplies<int>());
答案 1 :(得分:4)
This is basically just std::accumulate
。假设向量不为空,您可以将函数重写为:
template <typename C, typename F>
typename C::value_type fold(const C& container, const F& function) {
typename C::iterator cur = container.begin();
typename C::value_type init = *cur++;
return std::accumulate(cur, container.end(), init, function);
}
...
int sum = fold(myVector, std::plus<int>());
int difference = fold(myVector, std::minus<int>());
int product = fold(myVector, std::multiplies<int>());
现在,关于您的实施:
如上例所示,要在模板中声明类型参数,您需要使用typename
或class
关键字:template <typename T> int allVectorWithOperator( ... )
单独的*
将不是有效的语法。但是C ++提供了许多“函数对象”,它们包含这些运算符,因此您可以将它们与函数表示法一起使用。例如,
std::multiplies<int> f; // f is a now function that multiplies 2 numbers
int product = f(5, 7); // p == 35;
所以你可以写:
template<typename T>
int allVectorWithOperator(vector<int> &myVector, T func) {
....
for (it = myVector.begin(); it != oneBeforeFinal; ++ it) {
sum = func(*it, *(it+1));
}
}
另外,一些小问题:(1)通常我们将迭代器与!=
而不是<=
进行比较,因为许多迭代器不支持<=
运算符,(2){{ 1}}通常比++it
更有效。
宏和模板在不同阶段处理。特别是,您无法将模板或函数参数传递给宏,因为在考虑模板时已经评估了所有宏。要实现您的语法,必须将整个it++
写为宏,例如(假设可以使用C ++ 11):
allVectorWithOperator
是的,这是完全混乱,所以如果可能的话,你不应该使用宏。 BTW,#define allVectorWithOperator(container, binaryOp) \
([&]() -> std::remove_reference<decltype(*(container).begin())>::type { \
auto&& c = (container); \
auto cur = c.begin(); \
auto val = *cur++; \
auto end = c.end(); \
while (cur != end) { val binaryOp##= *cur++; } \
return val; \
}())
表示将#OP
转换为字符串。你真的不需要OP
。