【发布时间】:2012-07-26 01:53:59
【问题描述】:
假设我正在创建一个函数来复制一个值:
template<class ItInput, class ItOutput>
void copy(ItInput i, ItOutput o) { *o = *i; }
如果i 和o 指向同一个对象,我想避免分配,因为这样分配就没有意义了。
显然,我不能说if (i != o) { ... },因为i 和o 可能属于不同类型,并且因为它们可能指向不同的容器(因此无法比较)。不太明显的是,我也不能使用重载的函数模板,因为迭代器可能属于不同的容器,即使它们具有相同的类型。
我最初的解决方案是:
template<class ItInput, class ItOutput>
void copy(ItInput i, ItOutput o)
{
if (&*o != static_cast<void const *>(&*i))
*o = *i;
}
但我不确定这是否有效。如果*o 或*i 实际上返回一个对象而不是引用呢?
一般有没有办法做到这一点?
【问题讨论】:
-
哦,我明白了......'aite。喜欢这个:)
-
当您说“...如果输入和输出相同...”时,您是指相同的值,还是指向容器中相同位置的迭代器?
-
我同意 w/chrad,您的解决方案很好。您对 *o/*i 返回对象的担忧具有更重要的含义,因为函数
*o = *i;在这种情况下也不起作用,因为两者属于同一类型。 -
迭代器需要什么类别的迭代器?它们实际上可以是输入和输出迭代器吗?输入迭代器只是单次传递,因此您不能将其间接两次。 严格来说,只有输入迭代器可以是代理迭代器(
operator*返回对象而不是引用的迭代器)。前向、双向和随机访问迭代器不能返回代理。在实践中,并不总是遵循这一点,因为拥有一个提供随机访问的代理迭代器非常有用(另外,我不知道如何在不这样做的情况下有效地实现vector<bool>) -
@LucDanton:重要的规则在 §24.2.5[forward.iterators]/6 中,它要求两个前向迭代器
a和b,“如果a和 @987654336 @ 都是可取消引用的,然后a == b当且仅当*a和*b绑定到同一个对象。”只有在间接产生引用时才能满足该要求。