2011-04-05 97 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處相遇時,神祕內的循環結束。