我正在学习c ++并尝试理解模板。
从我可以收集的内容中,模板用于定义对象集合,只要所有对象都属于同一类型,我们都不关心它们。
另一方面,如果我们需要对提供的对象进行操作,那么多态性是更好的选择,因为我们有一个类型可以保证方法的实现。
这就是它的全部吗?或者模板可以用于其他事情吗?像收藏品一样。
答案 0 :(得分:0)
以下是Stroustrup本人的一个例子:
#include <string>
#include <iostream>
#include <utility>
#include <stdexcept>
template<typename Iter>
void osprintf(::std::ostream &os, Iter begin, const Iter &end)
{
bool saw_brace = false;
while (begin != end) {
const char c = *begin;
if (c == '{') {
saw_brace = true;
} else if (saw_brace && c == '}') {
throw ::std::runtime_error("More format specifiers than arguments in osprintf");
} else if (saw_brace) {
os << '{' << c;
saw_brace = false;
} else {
os << c;
}
++begin;
}
if (saw_brace) {
os << '{';
}
}
template<typename Iter, typename T, typename... Args>
void osprintf(::std::ostream &os, Iter begin, const Iter &end, T &&value, Args && ...args)
{
bool saw_brace = false;
while (begin != end) {
const char c = *begin;
if (c == '{') {
saw_brace = true;
} else if (saw_brace && c == '}') {
os << value;
osprintf(os, ++begin, end, ::std::forward<Args>(args)...);
return;
} else if (saw_brace) {
os << '{' << c;
saw_brace = false;
} else {
os << c;
}
++begin;
}
if (saw_brace) {
os << '{';
}
throw ::std::runtime_error("More arguments than format specifiers for osprintf");
}
template<typename T, typename... Args>
void osprintf(::std::ostream &os, const ::std::string &format, T &&value, Args && ...args)
{
osprintf(os, format.begin(), format.end(), ::std::forward<T>(value), ::std::forward<Args>(args)...);
}
int main()
{
osprintf(::std::cout, "This should be a 5: {}, and this should be a 'foobar': '{}'\n", 5, "foobar");
return 0;
}
这是C printf
的模板化版本,它是类型安全的,并使用“{}
”作为格式化占位符。模板程序(运行编译器的程序)查看参数列表并构建一个printf函数,该函数扫描格式字符串中的“{}
”对,并用参数列表中的下一个值替换它们。如果参数的数量与“{}
”对的数量不匹配,则会引发异常。
C ++中的模板远比Java中的模板强大得多。这是Java设计者的一个有目的的决定。他们从Java中切断了C ++模板的强大功能,因为这种功能是C ++复杂性的重要来源,他们不希望Java中存在这种复杂性。这个原因非常类似于Java中没有运算符重载的原因,而且存在于C ++中。
还有无数其他例子。拥有编译器执行的程序语言以使其编译的程序非常强大,并且这一功能在C ++模板之前只在Common Lisp中可用。
有非常好的'宏'语言(如m4),但这些语言并没有以相同的方式与它们生成的程序交织在一起,所以很难做出关于宏如何扩展的良好决策根据正在制作的节目的语言细节。
C ++的模板仍然不如Common Lisps宏强大。在Common Lisp中,宏可用于创建之前不存在的全新控制结构,而C ++通常只能用于在编译时创建类型或函数。