对 C++ 模板感到困惑

Posted

技术标签:

【中文标题】对 C++ 模板感到困惑【英文标题】:Getting confused with C++ template 【发布时间】:2011-06-10 08:02:26 【问题描述】:

我在看一些c++代码,不明白这种情况下模板声明的目的:

template<> void operator>>(const ClassA& s, const ClassB d) ...

template&lt;&gt; 的语义是什么?

【问题讨论】:

【参考方案1】:

这确实是模板专业化,正如前面提到的其他人一样。必须有一些之前声明过的函数模板,如:

template<typename T, typename U>
void operator>>(const T& s, const U d) ...

然而,这是相当误导的。完全删除template&lt;&gt; 会更好,所以operator&gt;&gt; 只会超载。函数模板特化的问题在于它可能会在存在重载函数的情况下导致意外行为(并且operator&gt;&gt; 有很多重载),因为特化不会重载。这意味着编译器首先为函数选择最合适的重载,然后,如果选择的重载是函数模板,它会查找模板特化以查看是否有合适的重载。

一个经典的例子(不幸的是,我不记得我在哪里读过它)。考虑这个重载的函数模板:

template <typename T>
void Function(T param);

template <typename T>
void Function(T* param);

template <>
void Function(int* param);

main()

  int i = 5;
  Function(&i);

正如预期的那样,int* 的模板特化被调用了。但只需更改函数定义的顺序即可:

template <typename T>
void Function(T param);

template <>
void Function(int* param);

template <typename T>
void Function(T* param);

main()

  int i = 5;
  Function(&i);

现在调用T* 的通用模板,因为我们专门为T 设计模板,而不是T*,第二个模板更适合我们的调用。如果我们重载函数而不是专门化模板,则可以避免这种情况:

void Function(int* param);

现在声明的顺序无关紧要,我们将始终调用int*的重载。

更新:现在我知道该归功于谁了。我在 Herb Sutter 的 article 中读到了这一点。该示例由 Peter Dimov 和 Dave Abrahams 提供。

【讨论】:

感谢您的回复,所以这是另一个使语言复杂化的技巧。就像重载一样,我认为这不是一个好主意,请参阅:gbracha.blogspot.com/2009/09/systemic-overload.html @mathk:我不同意您链接的文章中的大多数想法。 您不同意设计 Java 的人之一。你不喜欢什么? @mathk:他似乎也不同意自己的观点,因为 Java 允许他批评的所有这些事情(例如构造函数和函数重载)。 这让他真正了解了为什么这不是一个好主意。【参考方案2】:

这是Template specialization

【讨论】:

【参考方案3】:

当您想为特定模板类型提供 special 处理程序时,可以使用此语法。考虑:

// A normal template definition.
template <typename AType>
whoami ()    std::cout << "I am an unknown type.";  

// Now we specialize.
template <>
whoami<int> ()    std::cout << "I am an integer!";  

还有一些其他的废话,特别是“部分专业化”,但这是template &lt;&gt;的基本功能。

【讨论】:

【参考方案4】:

这是一个template specialization:(完全或部分)解析特定类型的模板。 (您的特定示例似乎是一个完整的特化,因为其中没有更多的模板参数未解决。如果模板有多个参数,而您只特化其中一些参数,则称为 部分模板特化 )

这允许为给定模板提供特定类型的优化,或执行许多巧妙的技巧,例如检测变量的静态类型等。

【讨论】:

éter 我认为 OP 提供的示例无效。如果我没记错的话,你不能专门化一个函数,你必须重载它。专业化仅适用于课程。 @Victor,与类模板相比,模板函数确实有一些限制;不知道这如何(以及是否)改变了 C++03 及更高版本。但是,C++ FAQ 中的链接示例似乎是函数模板专业化,所以我认为它应该可以工作:-) éter 嗯,很有趣,我只是在几个编译器上尝试过,它确实接受了代码。但是,看起来部分专业化不适用于功能。这一定是我想的。 @Victor T:就是这样,部分函数模板特化无效,但接受完全特化。然而,专门化一个函数模板很少是一个好主意(我试图在我的回答中解释这一点)。 @Victor:部分特化不适用于 C++03 中的函数,但完全特化是可以的。

以上是关于对 C++ 模板感到困惑的主要内容,如果未能解决你的问题,请参考以下文章

在 Joomla 替代布局和使用 K2 模板之间感到困惑

C++初始化模板类

我刚开始使用方法。这是一个模板,我对如何执行这些方法感到困惑。有人可以告诉我如何做被问到的事情吗?

模板函数作为模板参数

对 nib 文件感到困惑

对 C++ 迭代器感到困惑