C++模板部分特化问题

5

我在以下代码的编译时遇到了问题:

  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;

错误信息是(在标记为“HERE”的行上):
error: 'std::vector' is not a type

当然,我已经包含了来自std的向量!有什么建议吗?我已经试验了一段时间,但是现在需要帮助了 :-) 我需要部分特化初始模板声明,以便我可以让编译器根据容器C的实际类型切换实现(将为集合、向量、范围等各自提供is_in,每次都使用不同的算法)。
谢谢!
3个回答

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);
}

不好啦! :-) 当然,这会限制我的努力 - 我必须推出一个函数对象... - Frank

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<T, template<class _Tp, class _Alloc> class std::vector>' 明确不被允许。 - Frank
@Frank 不要只是复制粘贴代码。我在帖子中加了强调。 - Luc Danton
@Frank 我的意思是,“当然”它不能工作。这就是我说的。 - Luc Danton
1
是的,我知道。我只是提供你为了教育而得到的错误信息。 - Frank

0

我不知道它是否有效(因为模板总是让我头疼),但是试一下怎么样?

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

因为这是一种特殊化。

编辑:其他人已经澄清了这一点,但我会为完整性添加它。上面的代码实际上是一种重载而不是部分特化,但部分函数特化也无法实现。


1
这不是一种特化。它是一个重载的函数模板。 - Nawaz
@Nawaz 是的,你说得对。Luc的回答澄清了语法差异,但部分特化在任何情况下都是不允许的,正如你在你的回答中所说的那样。 - Christian Rau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接