与宏模板功能 - 积累矢量(Template function with macro - accum

2019-09-22 04:31发布

我想创建得到函数vector<int>跑了过来他的所有元素和“总和”,根据特定的运营商他们我选择。

例如, v1 = [3,6,7]所以我可以由本函数计算- 3+6+73-6-73*6*7等。

为此,我做了 -

#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    

}

我不模板的这种情况下,控制得很好,从而你可以看到这个代码不工作,但我想你明白什么是我的目标。 我怎样才能修复它工作得很好?

编辑:

根据2回答我得到了我改变了代码段 -

#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;

}

它做工精细! 事实上,我got accumulate the vector with * is :72

Answer 1:

这基本上是刚刚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>());

现在,关于您的实现:

  1. 如该示例中所示的上方,来声明在模板的类型参数,则需要具有typenameclass关键字: template <typename T> int allVectorWithOperator( ... )

  2. 一个孤独的*不会是一个有效的语法。 但是,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) ++it是效率比it++一般。

  3. 宏和模板,在不同的阶段进行处理。 特别是,你不能在模板或函数参数传递给宏,因为当模板被认为是所有宏都已经评估。 为了实现你的语法,整个allVectorWithOperator必须写成宏,例如(假设C ++ 11可以使用):

     #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; \ }()) 

    是的,它是一个完整的混乱,所以你应该不喜欢,如果可以使用宏。 BTW, #OP意味着打开OP到一个字符串。 你并不真正需要的#



Answer 2:

标准库已经在操作<algorithm> <numeric>

您可以使用

int sum = std::accumulate(MyVector.begin(), MyVector.end(), 0);

加起来的所有元素。

如果要计算产品(而不是使用默认的operator+ ),你可以传递一个额外的参数

int product = std::accumulate(MyVector.begin(), MyVector.end(), 1,
                              std::multiplies<int>());


文章来源: Template function with macro - accumulate on vector