代码之家  ›  专栏  ›  技术社区  ›  TimW

专业化功能模板vs功能过载vs类专业化

  •  8
  • TimW  · 技术社区  · 17 年前

    this article 从赫伯·萨特那里,人们应该总是挑 专业类 超过 当然结束了 专用功能模板 .

    • 我们不能专门化函数模板。

    他为什么不选我的专业功能
    读完这篇文章后,我再也没有使用过专用函数模板。

    例子:

    template <class T> void foo( T t);
    

    我们应该这样编写foo,这样我们就可以用类模板而不是函数专门化它。

    template<class T> 
    struct FooImpl;
    
    template <class T> void foo( T t) {
        FooImpl<T>::foo(t);
    }
    

    现在我们可以专门化模板,而不必担心重载规则,我们甚至可以像这样对模板进行分区专门化:

    template<class U, class V> 
    struct FooImpl< QMap< U, V > >;
    


    问题是这样的。


    为什么?
    根据我目前掌握的信息,我觉得这很反常,因为我知道我可以做对,但我知道在我之后的人会碰壁。

    已经有一些GOTWCA文章的链接,所以你一定读过这篇文章。这意味着投票人必须有一些额外的信息,请站起来告诉我。

    4 回复  |  直到 17 年前
        1
  •  4
  •   Community Mohan Dere    9 年前

    显式专门化函数模板的问题仅适用于函数也重载的情况:

    template <typename T> void foo (T*);   // #1
    
    template <typename T> void foo (T);    // #2
    template <> void foo<int*> (int*);
    
    int main () {
      int * i;
      foo (i);  // Calls #1 not specialization of #2
    }
    

    如果没有#1重载,代码将按预期工作。然而,一个开始没有重载的函数可能会在将来维护代码时添加重载。

    TimW answer

    template <typename T> class DoFoo {
        static void do (T) { /* default behaviour */ }
    };
    template <> class DoFoo<int*> {
        static void do (int*) { /* int * behaviour */ }
    };
    
    template <typename T> void foo (T t)
    {
      DoFoo<T>::do (t);
    }
    

    如果'foo'被重载,那么至少对开发人员来说,这个函数不会被调用是更清楚的,也就是说,开发人员不需要成为标准专家来了解专业化规则如何与重载解析相互作用。

    然而,最终编译器生成的代码将是相同的,这纯粹是开发人员的代码理解问题。

        2
  •  3
  •   Community Mohan Dere    9 年前

    你在这里假设SO选民都是大师——他们不是。 许多技术上不正确的答案都得到了支持。

    作为《 the answer that I think you are referring to , 正如我在评论中所说,这不是问题 模板专业化。我想本可以删除这个答案,但它在技术上是正确的,似乎确实引发了关于这个话题的一些有益的辩论。

    请注意,目前它的得分排名第三(可能在此之后被否决),另一个使用完全不同方法解决问题的答案已被接受。

        3
  •  2
  •   Tobias    17 年前

    正如尼尔所指出的,大多数正确答案都会被投票通过。根据我的经验,已经名列前茅的答案往往会获得更多的支持票。

    至于为什么:我想专门的函数模板更容易理解,这就是为什么它们在示例代码中更受欢迎。

        4
  •  2
  •   jpalecek    17 年前

    首先,我不是(不管你说什么)的支持者。

    您的部分专业:

    template<class U, class V> 
    struct FooImpl< QMap< U, V > >;
    

    template<class U, class V> 
    void foo(QMap< U, V > ) { ... }
    

    等等

    即使SFINAE是可能的,函数(模板)偏序也遵循与模板专门化解析几乎相同的规则。..