2011-04-05 98 views
0

这个问题的正确答案是D,但是我很困惑的是什么时候在类dunno中的add操作发生的确切时间?数字如何被添加?关于函子的问题

考虑以下部分的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,7,8,9, (dod不改变矢量)

(d)如果矢量由整数1,2,3,4,5,6,7以该顺序组成,则与在左边的第一项,则输出是8,8,8,5,6,7。

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

回答

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 <int>其中有方法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 
0

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

1

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