2012-04-07 82 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>());