2012-04-07 88 views
0

我現在正在閱讀「C++標準庫」。我在5.7章中發現了一些困惑的東西。我們知道,我們可以編寫自己的函數和算法來處理集合的元素。當然,這些操作也可能是通用的。 讓我們來看一個例子。下面的代碼定義了一個泛型函數,它打印一個可選字符串,後跟所有傳入容器的元素。C++:使用用戶定義的通用函數

template <class T> 
inline void PRINT_ELEMENTS(const T& col1,const char *optcstr = "") 
{ 
    typename T::const_iterator pos; 
    for(pos = col1.begin();pos != col1.end();++pos) 
     cout << *pos << " "; 
    cout << endl; 
} 

和POS被聲明爲具有通過容器類型的迭代器類型,typyname必要指定爲const_iterator是一種類型的,而不是類型T的值

我有幾個問題:

(1)當我刪除類型名在代碼中,它運作良好。 請參見下面的代碼:

#include <iostream> 
#include <vector> 
#include <set> 
#include <algorithm> 

using namespace std; 

int square (int value) 
{ 
    return value*value; 
} 

template <class T> 
inline void PRINT_ELEMENTS(const T& col1,const char *optcstr = "") 
{ 
    /*typename T::const_iterator pos;*/ 
    T::const_iterator pos; 

    for(pos = col1.begin();pos != col1.end();++pos) 
     cout << *pos << " "; 
    cout << endl; 
} 

int main() 
{ 
    set<int> coll1; 
    vector<int> coll2; 

    // insert elements from 1 to 9 into coll1 
    for (int i=1; i<=9; ++i) { 
     coll1.insert(i); 
    } 
    /*PRINT_ELEMENTS(coll1,"initialized: ");*/ 

    // transform each element from coll1 to coll2 
    // - square transformed values 
    transform (coll1.begin(),coll1.end(), // source 
        back_inserter(coll2), // destination 
        square);      // operation 

    PRINT_ELEMENTS(coll2,"squared:  "); 
} 

它的工作原理well.Its輸出爲: enter image description here

爲什麼類型名稱沒有必要? 我不是很瞭解它的功能。 有人可以詮釋我嗎?

(2) 爲什麼我不能使用矢量::迭代器輸出的元素是這樣的:

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

int main() 
{ 
    set<int> intSet; 
    vector<int> intVector2; 

    for (int i = 1;i <= 10;++i) 
     intSet.insert(i); 

    transform(intSet.begin(),intSet.begin(), 
     back_inserter(intVector2), 
     negate<int>()); 

    vector<int>::iterator iter = intVector2.begin(); 
    for(;iter != intVector2.end();++iter) 
     cout << *iter << endl; 
} 

它輸出nothing.I使用Visual Studio 2008來運行我的代碼。 有人可以幫助我嗎?非常感謝。

回答

4

typename是沒有必要的因爲某些版本的Visual Studio不符合標準。新版本和其他編譯器對此更嚴格,如果沒有它,代碼將無法編譯。

你的第二個例子不工作,因爲你通過begin()begin(),不begin()end()

transform(intSet.begin(),intSet.begin(), 

哎呦。

0

(1)

類型名稱消歧有助於其操作數爲在某些情況下一種類型。

最突出的似乎是在類聲明的範圍:

class X 
{ 
    ... 
    typename Y::Z w; // necessary 
}; 

(2)

有一個錯字...

- transform(intSet.begin(),intSet.begin(), 
    back_inserter(intVector2), 
    negate<int>()); 


+ transform(intSet.begin(),intSet.end(), 
    back_inserter(intVector2), 
    negate<int>());