簡體   English   中英

C++:使用用戶定義的泛型函數

[英]C++:Use user-defined generic functions

我現在正在閱讀《C++ Standard Library》。我發現第 5.7 章有些混亂。 我們知道,我們可以編寫自己的函數和算法來處理collections的元素。當然這些操作也可以是泛型的。 讓我們看一個例子。下面的代碼定義了一個通用的 function,它打印一個可選的字符串,后跟傳遞的容器的所有元素。

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)當我在代碼中擦除typename時,效果很好。 請參閱以下代碼:

#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:     ");
}

它運作良好。它的 output 是:在此處輸入圖像描述

為什么?不需要typename嗎? 而且這里的function我不是很懂。 有人可以給我翻譯嗎?

(2)為什么我不能使用vector::iterator來對output這樣的元素:

#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;
}

它什么都不輸出。我使用 Visual Studio 2008 來運行我的代碼。 有人可以幫我嗎?非常感謝。

typename不是必需的,因為某些版本的 Visual Studio 不符合標准。 較新的版本和其他編譯器對此更加嚴格,如果沒有它,您的代碼將無法在那里編譯。

您的第二個示例不起作用,因為您通過了begin()begin() ,而不是begin()end()

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

哎呀。

(1)

typename 在某些情況下有助於消除其操作數作為類型的歧義。

最突出的似乎是在 class 聲明的 scope 中:

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>());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM