簡體   English   中英

C ++模板+迭代器(noob問題)

[英]C++ Template + Iterator (noob question)

我的免責聲明是我在一周前開始自學C ++課程,而我之前的編程經驗是動態語言(Python,javascript)。

我正在嘗試使用通用函數迭代矢量的內容來打印出項目:

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

using std::vector;
using std::cout;

template <class T>
void p(T x){
    cout << x;
}

int main () {

    vector<int> myV;

    for(int i = 0; i < 10; i++){
        myV.push_back(i);
    }

    vector<int>::const_iterator iter = myV.begin();

    for_each(iter, myV.end(), p);

    return 0;
}

代碼無法編譯。 有人解釋原因嗎?

編輯:編譯器錯誤:

error: no matching function for call to 'for_each(_gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<const int, _gnu_norm::vector<int, std::allocator<int> > >, __gnu_debug_def::vector<int, std::allocator<int> > >&, __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<int, __gnu_norm::vector<int, std::allocator<int> > >, __gnu_debug_def::vector<int, std::allocator<int> > >, <unknown type>)'

謝謝!

嘗試:

for_each(myV.begin(), myV.end(), p<int>);

你的代碼中有兩個錯誤:

  • 迭代器不是同一類型
  • 函數指針實際上不是指針。
    • 通常模板化的函數可以從那里參數推導出來。 但在這種情況下,您實際上並沒有使用它,而是將它(或其地址)傳遞給函數(因此模板函數推導的常規規則不起作用)。 由於編譯器無法推斷出您需要使用哪個版本的函數'p',因此您必須明確。

還有一個很好的輸出迭代器可以做到這一點:

std::copy(myV.begin(),myV.end(), std::ostream_iterator<int>(std::cout));

另請注意,很少有編譯器可以在函數指針調用中優化代碼。
雖然如果它是一個仿函數對象,大多數都能夠優化調用。 因此,以下可能是函數指針的可行替代方案:

template<typename T>
struct P
{
    void operator()(T const& value) const
    {
        std::cout << value;
    }
};

....

for_each(myV.begin(), myV.end(), P<int>());

另一個說明:
使用模板化方法/函數時,通常使用const引用而不是值。 如果要復制的類型很昂貴,那么按值傳遞將生成一個可能不符合預期的復制結構。

Martin的解決方案和你的解決方案不起作用的原因是p是一個函數模板,而不是一個實際的函數。 模板函數沒有可以采用的地址,也沒有傳遞給函數。 您必須實例化模板函數,以創建可以使用的實際函數。

你的問題是你必須將一些“可調用的實體”傳遞給std::for_each 這可能是一個函數對象(這是一個重載函數調用操作符的類)或一個函數指針。 (無論何處需要函數指針,您都可以使用匹配的原型傳遞函數的名稱 - 函數名稱會隱式轉換為函數地址。)

但是,你的p不是函數,它是一個函數模板 功能模板就是:用於創建函數的模板。 您需要傳遞這樣一個創建的函數而不是模板的名稱。 讓編譯器從函數模板創建函數的機制通常稱為模板實例化 所以你需要一個模板實例。 無論何時使用這樣的實例,都會由編譯器隱式創建。

所以,正如其他人已經說過的那樣,你需要顯式地將p<int>傳遞給std::foreach

std::for_each(myV.begin(), myV.end(), p<int>);

我沒有在C ++中使用for_each,但我會寫同樣的循環:

vector<int>::iterator iter;

for(iter = myV.begin(); iter != myV.end(); iter++) {
    p(iter);
}

暫無
暫無

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

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