关于仿函数的问题

时间:2011-04-05 02:29:07

标签: c++

对此的正确答案是D,但我感到困惑的是,什么时候dunno课程中的添加操作到底是什么时候?如何添加数字?

  

考虑以下部分C ++代码:

#include <vector>
#include <iostream>
using namespace std;

template<class Iter, class Formatter>
void mystery(Iter front, Iter end, Formatter doSomething)
{
    while (front != end)
    {
        doSomething(*front, *end):
        front++; end--;
    }
}
template <class T> class dunno
{
public:
    void operator()(T & a, T & b)
    {
        a = a + b;
    }
}
int main()
{
    vector<int> v; ... // insert an odd number of elements into the vector
    vector<int>::iterator it1 - v.begin();
    vector<int>::iterator it2 - v.end();
    it2--;
    dunno<int> d;
    mystery<vector<int>::iterator, dunno<int> >(itl, it2, d);
    for (int i = 0; i < v.size(); i++) cout << v[i] << endl;
    return 0;
}
  

如果假设所有迭代器都是双向且非常量的,则下列哪个语句都是真的?

     

(a)由于神秘参数列表中的类型不匹配,此代码无法编译。

     

(b)由于模板实例化中的语法错误,此代码无法编译。

     

(c)如果向量按顺序由整数1,2,3,4,5,6,7组成,左边第一项,则输出为1,2,3,4, 5,6,7。(即代码不会改变矢量。)

     

(d)如果向量按顺序由整数1,2,3,4,5,6,7组成,左边第一项,则输出为8,8,8,4, 5,6,7。

     

(e)这些选项均未描述此代码的行为。

3 个答案:

答案 0 :(得分:1)

dunno functor的operator()在每次调用doSomething时都被称为神秘内容。由于参数是通过引用传递的,因此每次都会更新作为“a”传入的值。所以你最终得到的是一个包含1 + 7,2 + 6,3 + 5,4,5,6,7的列表。因为当迭代器在值4处相遇时,神秘内部的循环结束。

答案 1 :(得分:1)

当我们称之为神秘()

   | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

     ^                       ^
     |                       |
   front                    end


front   is from v.begin();
end     is from v.end() (note: this is one past the end)
        followed by a -- operator that moves it back one.

现在我们开始循环:

while(front != end)

因此,当它们不相等时,它会循环。并且在循环内部同时移动:

front++; end--;

所以每次迭代都是这样的:

Iteration 1:
   | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

     ^                       ^
     |                       |
   front                    end

Iteration 2:
   | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

         ^               ^
         |               |
       front            end

Iteration 3:
   | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

             ^       ^
             |       |
           front    end

The loop is not entered.
   | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

                 ^
                 |
           front   end

所以每次循环我们都会这样做:

doSomething(*front, *end):

现在doSomething是Formatter(模板参数)类型的对象,它解码为dunno&lt; int&gt;类型。其中包含方法void operator()(T & a, T & b),在替换模板参数T后,我们得到void operator()(int & a, int & b)

所以这一行:

doSomething(*front, *end):

是语法糖:

doSomething.operator()(*front, *end):

具有调用此运算符传递取消引用的迭代器作为参数的效果。这实际上与:

相同
Iteration 1:
    v[0]    = v[0] + v[6]; // Note v[0] == 1 v[6] == 7 etc.
  //v[0]    =  1   +   7;

Iteration 2:
    v[1]    = v[1] + v[5];
  //v[1]    =  2   +   6

Iteration 3:
    v[2]    = v[2] + v[4];
  //v[2]    =  3   +   5

因此,如果你的开始数组是:

1 2 3 4 5 6 7

最终结果是:

8 8 8 4 5 6 7

答案 2 :(得分:0)

dunno实例d作为参数传递给mystery,然后由形参参数doSomething指定,并在while循环中调用其operator()。