2012-10-15 87 views
1

看起來編譯器非常接近我想做的事情(因爲它調用了我的函數作爲候選者),但我不知道我做錯了什麼。爲什麼我的函數調用不匹配這個通用函數實現?

#include <stdio.h> 
#include <stdlib.h> 
#include <list> 

using namespace std; 

template <class U, template<class U> class T> 
void AppendSorted(T<U>& l, U val) 
{ 
    typename T<U>::reverse_iterator rt = l.rbegin(); 

    while(((*rt) > val) && (rt != l.rend())) 
    rt++; 

    l.insert(rt.base(), val); 
} 

int main(int argc, char* argv[]) 
{ 
    list<int> foo; 
    AppendSorted<int, list<int> >(foo, 5); 

    list<int>::iterator i; 
    for(i = foo.begin(); i != foo.end(); i++) 
    { 
     printf("%d\n",*i); 
    } 

    return 0; 
} 

我得到的錯誤是:

test.cpp: In function ‘int main(int, char**)’: 
test.cpp:21:43: error: no matching function for call to ‘AppendSorted(std::list<int>&, int)’ 
test.cpp:21:43: note: candidate is: 
test.cpp:8:6: note: template<class U, template<class U> class T> void AppendSorted(T<U>&, U) 
+1

你會abbend在初始插件在你AppendSorted,順便說一句,因爲你而()子句中的eval命令是要提領迭代指着rend()當列表爲空時。在while()條件中反轉表達式以避免這種情況。 – WhozCraig

+0

@WhozCraig:好點。 –

回答

2

這個簽名

template <class U, template<class U> class T> 
void AppendSorted(T<U>& l, U val) 

表明,將有一個具體類型(class U)和一個模板(template<class U> class T)。

這種調用

AppendSorted<int, list<int> >(foo, 5); 

提供了兩種具體類型,intlist<int>list是一個模板,list<int>是一個具體類型,一個模板實例,但不是一個模板。

只要改變函數接受具體類型的集合:

template <class U, class T> 
void AppendSorted(T& l, U val) 
{ 
    typename T::reverse_iterator /* or auto */ rt = l.rbegin(); 

    while((rt != l.rend()) && ((*rt) > val)) 
    rt++; 

    l.insert(rt.base(), val); 
} 

,讓編譯器推斷,而不是指定他們的類型參數。

AppendSorted(foo, 5); 
+0

將函數調用更改爲:AppendSorted (foo,5);導致相同的錯誤。 – dicroce

+0

我不能使用C++ 11(不幸的是),所以「自動」出來。當我聲明rt爲:T :: reverse_iterator(你是模板規範)我得到「'T'不是模板」,這就是迫使我使用我最初的模板規範。 – dicroce

+0

@dicroce:只是'T :: reverse_iterator'。'T'不是模板,它是'list '。而'list :: reverse_iterator'很好理解,而'list :: reverse_iterator'沒有。 –

2

std::list的模板接受兩個參數 - 不僅是一個。有第二個默認參數。

你會需要這樣的模板函數匹配列表:約std::set

template <class U, template<class U,class A> class T> 
void AppendSorted(T<U,std::allocator<T>>& l, U val); 

但什麼 - 它需要3個參數?

我不知道 - 也許可變參數模板,將有助於...

但就試試這個:

template <class U, class Container> 
void AppendSorted( Container& l, U val); 
1

std::list實際上有兩個模板參數:

#include <stdio.h> 
#include <stdlib.h> 
#include <list> 

using namespace std; 

template <class U, template<class> class AL, template<class,class> class T> 
void AppendSorted(T<U,AL<U>>& l, U val) { 
     typename T<U,AL<U>>::reverse_iterator rt = l.rbegin(); 

     while(((*rt) > val) && (rt != l.rend())) 
       rt++; 

     l.insert(rt.base(), val); 
} 

int main(int argc, char* argv[]) { 
     list<int> foo; 
     AppendSorted(foo, 5); 

     list<int>::iterator i; 
     for(i = foo.begin(); i != foo.end(); i++) { 
       printf("%d\n",*i); 
     } 

     return 0; 
} 

現在它將會編譯,但是你的代碼中有邏輯錯誤 - 你有最後一個迭代器。爲了解決這個問題,在你while循環,檢查rend()第一:

while(rt != l.rend() && *rt > val) 
相關問題