gpt4 book ai didi

c++ - 特化函数模板 vs 函数重载 vs 类特化

转载 作者:可可西里 更新时间:2023-11-01 18:27:00 27 4
gpt4 key购买 nike

根据 this article从 Herb Sutter 那里,人们应该始终选择 Class Specializing 而不是 Function Overload 并且肯定会选择 Specialized Function Templates

原因是

  • 特化不会重载。重载决议只选择一个基本模板(或一个非模板函数,如果有的话)。只有在决定要选择哪个基本模板并锁定该选择之后,编译器才会环顾四周,看看是否恰好有该模板的合适特化可用,如果有,就会使用该特化。
  • 我们不能部分特化函数模板。

我必须承认,在阅读这篇文章之前,我曾几次用头撞墙。 他为什么不选择我的专业功能......
阅读文章后,我再也没有使用过专用函数模板。

例子:

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


这是问题。

似乎 StackOverflow 成员更喜欢专用函数模板?
为什么?因为专用函数模板比​​重载解决方案和类特化获得更多的赞成票。
根据我目前掌握的信息,我发现它有悖常理,因为我知道我可以做对,但我知道在我之后的人会撞墙。

已经有一些指向 GOTWCA 文章的链接,因此您一定已经阅读了这篇文章。这意味着upvoters一定有一些额外的信息,请站出来赐教。

最佳答案

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

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 重载,代码将按预期工作。但是,开始时未被重载的函数可能会在代码维护到 future 时添加重载。

这是其中的一个例子,虽然我不想这么说,但 C++ 有太多方法可以做同样的事情。就个人而言,如果您发现需要专门化一个函数模板,那么我喜欢 TimW 建议的模式在他对 Neil Butterworth 的评论中 answer , IE。最好通过让当前函数分派(dispatch)调用专门的类模板来做到这一点:

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”被重载,那么至少开发人员更清楚这个函数不会被调用,即。开发人员无需成为标准专家即可了解特化规则如何与重载解决方案交互。

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

关于c++ - 特化函数模板 vs 函数重载 vs 类特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/994949/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com