【问题标题】:C++ template partial specialization questionC++模板偏特化题
【发布时间】:2011-06-09 19:54:21
【问题描述】:

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

  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 用于集合,一个用于向量,一个用于范围......,每次使用不同的算法)。

谢谢!

【问题讨论】:

    标签: c++ templates template-specialization


    【解决方案1】:

    标准不允许函数模板的部分特化。

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

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

    【讨论】:

    • 嘘! :-) 当然,这会减少我的努力——我必须推出一个函数对象......
    【解决方案2】:

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

    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
    }
    

    【讨论】:

    • 导致:错误:函数模板部分特化 'is_in class std::vector>' 是不允许的。
    • @Frank 不要只是复制和粘贴代码。不过,我在帖子中添加了重点。
    • @Frank 我的意思是当然它不起作用。我就是这么说的。
    • 是的,我知道。我只是提供您收到的教育错误消息。
    【解决方案3】:

    我不知道它是否有效(因为模板模板总是让我觉得很麻烦),但是尝试一下呢

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

    因为它是一个专业。

    编辑:其他人已经对此进行了澄清,但为了完整起见,我会添加它。上面的代码实际上是重载而不是偏特化,但偏函数特化无论如何都是不允许的。

    【讨论】:

    • 这不是专业。它的重载函数模板。
    • @Nawaz 哦,是的,你是对的。 Luc 的回答澄清了语法差异,但无论如何都不允许部分专业化,正如您在回答中所说的那样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    相关资源
    最近更新 更多