2015-01-12 362 views
0

編輯。請看我的評論。C++模板集合類型

我一直在努力與此一段時間了。我一直在編寫一個mergesort例程,對矢量進行操作(坦率地說,重新發明了這個輪子),並且我一直在將迭代器傳遞給我的排序函數。在排序功能中,我創建了一個臨時向量。現在,我希望它對任何元素類型進行操作,因爲代碼中沒有特定於int/double等的內容。我似乎無法讓我的模板定義工作。我已經嘗試了許多不同的方式來做到這一點。如果有人可能看看我寫在下面的小片段,並告訴我如何讓它工作,以便我可以接受vector :: iterator作爲函數參數,然後在函數本身中聲明和使用矢量,我真的很感激它。

#include <vector> 
using namespace std; 

template <typename T> 
void test(vector<T>::iterator myiter) { 
    typename vector<T> myvec; 
} 

這裏是我的編譯時錯誤:

$ make tmpl 
g++ -Wall -ggdb --std=c++11 tmpl.cc -o tmpl 
tmpl.cc:5:22: error: variable or field ‘test’ declared void 
void test(vector<T>::iterator myiter) { 
        ^
tmpl.cc:5:31: error: expected ‘)’ before ‘myiter’ 
void test(vector<T>::iterator myiter) { 

如果它的任何利益,這是完整的清單我正在使用的當前快照 - 和合並()是一個我正在掙扎着。我已經多次與不同類型的改變的模板語法失敗:

#include <iostream> 
#include <vector> 

template <typename Iter> 
void print_collection(Iter start, Iter end) { 
    std::cout << "collection = { "; 
    for(; start != end; ++start) { 
    std::cout << *start << ", "; 
    } 
    std::cout << "};" << std::endl; 
} 


template <typename T> 
void merge(std::vector<T>::iterator start, std::vector<T>::iterator pivot, std::vector<T>::iterator end, int left_len, int right_len) { 
    std::vector<T> temp; 
    std::vector<T>::iterator i, j; 
    i = start; 
    j = pivot; 
    while(i != pivot && j != end) { 
    if(*i <= *j) { 
     temp.push_back(*i); 
     ++i; 
    } else if(*i > *j) { 
     temp.push_back(*j); 
     ++j; 
    } 
    } 
    for(; i != pivot; ++i) { 
    temp.push_back(*i); 
    } 
    for(; j != end; ++j) { 
    temp.push_back(*j); 
    } 
    i = start; 
    j = temp.begin(); 
    for(; i != end, j != temp.end(); ++i, ++j) { 
    *i = *j; 
    } 
} 


template <typename Iter> 
void merge_sort(Iter start, Iter end, int len) { 
    if(len <= 1) { 
    return; 
    } 
    int odd, left_len, right_len; 
    Iter pivot; 
    odd = len % 2; 
    left_len = (len/2) + odd; 
    pivot = start + left_len; 
    right_len = len/2; 

    merge_sort(start, pivot, left_len); 
    merge_sort(pivot, end, right_len); 
    merge(start, pivot, end, left_len, right_len); 
} 


int main(void) { 
    std::vector<double> vl = { 1.1, 9.1, 2.1, 8.1, 3.1, 7.1, 4.1, 6.1, 5.1, 0.1 }; 
    print_collection(vl.begin(), vl.end()); 
    merge_sort(vl.begin(), vl.end(), vl.size()); 
    print_collection(vl.begin(), vl.end()); 
    return 0; 
} 

,這裏是從全面上市編譯錯誤:

$ make vec 
g++ -Wall -ggdb --std=c++11 vec.cc -o vec 
vec.cc:39:28: error: variable or field ‘merge’ declared void 
void merge(std::vector<T>::iterator start, std::vector<T>::iterator pivot, std::vector<T>::iterator end, int left_len, int right_len) { 
          ^
vec.cc:39:37: error: expected ‘)’ before ‘start’ 
void merge(std::vector<T>::iterator start, std::vector<T>::iterator pivot, std::vector<T>::iterator end, int left_len, int right_len) { 
            ^
vec.cc:39:69: error: expected ‘)’ before ‘pivot’ 
void merge(std::vector<T>::iterator start, std::vector<T>::iterator pivot, std::vector<T>::iterator end, int left_len, int right_len) { 
                    ^
vec.cc:39:101: error: expected ‘)’ before ‘end’ 
void merge(std::vector<T>::iterator start, std::vector<T>::iterator pivot, std::vector<T>::iterator end, int left_len, int right_len) { 
                            ^
vec.cc:39:106: error: expected primary-expression before ‘int’ 
void merge(std::vector<T>::iterator start, std::vector<T>::iterator pivot, std::vector<T>::iterator end, int left_len, int right_len) { 
                             ^
vec.cc:39:120: error: expected primary-expression before ‘int’ 
void merge(std::vector<T>::iterator start, std::vector<T>::iterator pivot, std::vector<T>::iterator end, int left_len, int right_len) { 
                                 ^
vec.cc: In instantiation of ‘void merge_sort(Iter, Iter, int) [with Iter = __gnu_cxx::__normal_iterator<double*, std::vector<double> >]’: 
vec.cc:88:45: required from here 
vec.cc:81:47: error: ‘merge’ was not declared in this scope 
    merge(start, pivot, end, left_len, right_len); 

^

+2

我已經花了很多年看着我認爲是重複的鏈接問題。在決定問我的問題之前,我花了一段時間進行交易,我想我已經提出了一個非常具體的問題,並將相當數量的工作簡單地提出來,足以證明它被視爲一個完全不同的問題。我很欣賞我可能錯過了模板的基本點,並且鏈接的答案對我沒有多大幫助。我不是那種經驗豐富的C++,如果有人能指出我正確的方向 –

回答

1

兩個問題:

  1. std::vector<T>::iterator的所有實例應該是typename std::vector<T>::iterator,因爲它是依賴的注意模板參數。究其原因,在規範問題Where and why do I have to put the "template" and "typename" keywords?

    這裏的錯誤消息解釋是,如果你compile with Clang更清晰:

    main.cpp:15:12: error: missing 'typename' prior to dependent type name 'std::vector<T>::iterator' 
    void merge(std::vector<T>::iterator start, std::vector<T>::iterator pivot, std::vector<T>::iterator end, int left_len, int right_len) { 
          ^~~~~~~~~~~~~~~~~~~~~~~~ 
          typename 
    main.cpp:15:44: error: missing 'typename' prior to dependent type name 'std::vector<T>::iterator' 
    void merge(std::vector<T>::iterator start, std::vector<T>::iterator pivot, std::vector<T>::iterator end, int left_len, int right_len) { 
                  ^~~~~~~~~~~~~~~~~~~~~~~~ 
                  typename 
    main.cpp:15:76: error: missing 'typename' prior to dependent type name 'std::vector<T>::iterator' 
    void merge(std::vector<T>::iterator start, std::vector<T>::iterator pivot, std::vector<T>::iterator end, int left_len, int right_len) { 
                          ^~~~~~~~~~~~~~~~~~~~~~~~ 
                          typename 
    main.cpp:17:3: error: missing 'typename' prior to dependent type name 'std::vector<T>::iterator' 
        std::vector<T>::iterator i, j; 
        ^~~~~~~~~~~~~~~~~~~~~~~~ 
        typename 
    
  2. Once you fix that,編譯器會告訴你,它不能推斷Tmerge被稱爲,因爲::左側的所有內容都是非推導的上下文。 merge爲什麼不應該被模板化爲T而不是迭代器類型,或者實際上爲什麼它必須被限制爲迭代器到std::vector(除了首先分配然後temp.begin()j時代碼中的一個地方,這可以通過添加另一個變量很容易固定):

    template <typename Iter> 
    void merge(Iter start, Iter pivot, Iter end, int left_len, int right_len); 
    

    但你創建一個std::vector<T>劃傷,所以我們現在需要弄清楚T,或迭代器的值類型。做到這一點的方法是通過std::iterator_traits

    typedef typename std::iterator_traits<Iter>::value_type T; 
    

枝節問題:i != end, j != temp.end()作爲循環條件變得毫無意義。推測你的意思是i != end && j != temp.end()

Demo

+0

非常感謝你。這真的是我想要的。有人可能會爭辯說,這不是我需要的哈哈。我設法得到了一點進一步,並且回來發佈更新。我認爲你的評論真的有助於澄清我的特定問題,而iterator_traits提示真的很有幫助!如果你有興趣,這就是我想出的。它的功能,但有很多的行李! http://coliru.stacked-crooked.com/a/e7fc65269ab56a8e –