【发布时间】:2011-07-15 12:24:44
【问题描述】:
引用this answer,第二个代码块。我的问题是:
如果我知道我将只处理std::lists<int>,并且只处理<int>。
有没有办法在不使用模板并且不按照 cmets 中的建议通过引用传递列表的情况下编写这个(第二个块和第三个块)?可以给我看看吗?
如果实现只涵盖一种类型,我认为避免使用模板是有意义的,对吗??? (还是我太懒了?)
【问题讨论】:
引用this answer,第二个代码块。我的问题是:
如果我知道我将只处理std::lists<int>,并且只处理<int>。
有没有办法在不使用模板并且不按照 cmets 中的建议通过引用传递列表的情况下编写这个(第二个块和第三个块)?可以给我看看吗?
如果实现只涵盖一种类型,我认为避免使用模板是有意义的,对吗??? (还是我太懒了?)
【问题讨论】:
这就是我的答案!
您可以将std::back_insert_iterator<std::list<int> > 传递给带有或不带有模板的函数。秘密地,您仍然通过引用传递列表,因为迭代器本身持有指向容器的引用或指针。
typedef std::back_insert_iterator<std::list<int> > OutputIterator;
void getInts(OutputIterator out) {
for (int i = 0; i < 10; ++i) {
*(out++) = i;
}
}
然后调用者这样做:
std::list<int> l;
getInts(std::back_inserter(l));
在back_inserter 是一个函数模板,back_insert_iterator 是一个类模板的意义上,你仍然在“使用模板”,但同样list 也是如此。这样您就无需编写任何自己的模板。
我不同意,如果你只对一种类型感兴趣,那么避免使用模板必然是有意义的——C++ 模板的副作用是通过模板参数推导进行类型推断,这意味着你不必写出荒谬的东西像 std::back_insert_iterator<std::list<int> > 这样的类型,甚至在 typedef 中出现一次。从代码中可以看出,避免模板并不是懒惰,实际上编写模板的文本更少,因为您不必提及类型。但是,如果出于某种原因您想限制该功能仅适用于列表,并且只能附加到列表的后面,那么您可以继续。
【讨论】:
*(out++) 部分吗?这是什么构造?我在哪里可以读到它?只是典型的迭代器语法?
*out = i; ++out; - 将值分配给取消引用的迭代器,然后将其递增以准备下一个值。我说“或多或少”,因为就迭代器接口而言,它具有相同的定义含义,但实际上并没有什么可以阻止迭代器对后增量和预增量或通过分配具有不同的副作用复制与原始,因此并不完全相同。