2012-10-15 50 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) 
相关问题