2011-06-09 82 views
5

我在编译用下面的代码时间麻烦:C++模板部分特例问题

template <typename T, 
      template <class T, class Allocator = std::allocator<T> > class C> 
    bool is_in(const C<T>& a, const C<T>& b); 

    template <typename T, std::vector> // HERE 
    bool is_in(const std::vector<T>& a, const std::vector<T>& b) 
    { 
    return false; // implementation tbd 
    } 

... 

vector<int> a, b; 

cout << is_in(a,b) << endl; 

该错误消息是(在标出“这里”):

error: 'std::vector' is not a type 

(的当然,我包括向量从std!)。任何建议?我弄了一会儿,但我已经到了可以使用一些帮助的地步:-)我需要部分地专门化最初的模板声明,以便我可以让编译器根据实际的类型容器C(将有一个is_in用于集合,一个用于矢量,一个用于范围......,每次都有不同的算法)。

谢谢!

回答

6

标准不允许功能模板的部分特化。

一个简单的解决方案是:使用过载。

template <typename T> 
bool is_in(const std::vector<T>& a, const std::vector<T>& b) 
{ 
    return false; // implementation tbd 
} 

这是重载函数模板。其非部分专业化。

或者,你可以这样做:

namespace detail 
{ 
    template<typename T, typename C> 
    struct S 
    { 
     static bool impl(const C & a, const C & b) 
     { 
      //primary template 
      //... 
     } 
    } 
    template<typename T> 
    struct S<T, std::vector<T> > 
    { 
     static bool impl(const std::vector<T> & a, const std::vector<T> & b) 
     { 
      //partial specialization for std::vector 
      return false; 
     } 
    } 
} 

template <typename T, template <class T, class Allocator = std::allocator<T> > class C> 
bool is_in(const C<T>& a, const C<T>& b) 
{ 
    return detail::S<T, C<T> >::impl(a,b); 
} 
+1

一种解决方法是将功能的一类。 – 2011-06-09 20:02:21

+0

Booouuuhhhh! :-)当然,这将削减我的努力 - 我将不得不推出一个功能对象... – Frank 2011-06-09 20:03:14

0

我不知道,如果它(为模板,模板始终是一个麻烦,我的心),但对于只是想

template <typename T> 
bool is_in(const std::vector<T>& a, const std::vector<T>& b) 
{ 
    ... 
} 

,因为它是一个专业化。

编辑:其他人已澄清这一点,但我会补充它的完整性。上面的代码实际上是一个重载而不是局部特化,但是不允许部分函数特化。

+1

这不是一个专业化。它的重载函数模板。 – Nawaz 2011-06-09 20:05:25

+0

@Nawaz哦,是的,你说得对。吕克的答案阐明了语法的差异,但是也不允许部分特化,正如你在答案中所说的那样。 – 2011-06-09 20:16:54

1

功能模板部分专业化是不允许允许。在任何情况下,你都没有使用模板特化语法,你实际上正在编写一个额外的重载。试试这个:

template <typename T> 
bool is_in(const std::vector<T>& a, const std::vector<T>& b) 
{ 
    return false; // implementation tbd 
} 

如果偏特被允许,它应该是这样的,而不是:

template <typename T> // std::vector is not a template parameter, 
         // so we wouldn't put it here 
bool is_in<T, std::vector>(const std::vector<T>& a, const std::vector<T>& b) 
// instead, it'd appear^here, when we're specializing the base template 
{ 
    return false; // implementation tbd 
} 
+1

这会导致:错误:函数模板部分特化'is_in 类std :: vector>'是不允许的。 – Frank 2011-06-09 20:07:37

+0

@Frank不要只是复制和粘贴代码。尽管我在帖子中强调了这一点。 – 2011-06-09 20:09:52

+0

我没有复制和粘贴。我早些时候曾经尝试过。 – Frank 2011-06-09 20:10:55