在C ++中,如果你有一个使用移动构造函数的“复制”用户定义类型的对象的for循环,那么如果你使用++i
或{{ 1}}作为循环计数器?
我知道这个问题看起来很模糊,但我(我相信)在电话采访中问了这个问题。我不确定我是否正确地理解了这个问题,面试官把这个看作是我不知道答案,并简短地缩短了面试时间。
他能得到什么?
答案 0 :(得分:10)
在C ++中,如果你有一个for循环使用移动构造函数“复制”用户定义类型的对象[...]
首先,移动构造函数用于移动构造,这通常意味着你不是“复制”:你可以实现移动作为复制 - 事实上,一个类是复制 - 可构造性也是可移动构造的 - 但是为什么明确定义移动构造函数呢?
[...]如果你使用++ i或i ++作为循环计数器会有什么不同吗?
这取决于i
是什么。如果它是标量对象,如int
,则根本没有区别。
如果i
是类型迭代器,另一方面,++i
应该更有效率(纯理论基础),因为operator ++
的实现不会有在迭代器本身递增之前创建要返回的迭代器的副本。
例如,这里是stdlibc ++如何定义std::list
的迭代器类型的增量运算符:
_Self&
operator++()
{
_M_node = _M_node->_M_next;
return *this;
}
_Self
operator++(int)
{
_Self __tmp = *this;
_M_node = _M_node->_M_next;
return __tmp;
}
正如您所看到的,后缀版本(接受虚拟int
的那个)还有更多工作要做:它需要创建要重新生成的原始迭代器的副本,然后更改迭代器的内部指针,然后返回副本。
另一方面,前缀版本只需改变内部指针并返回(引用)本身。
但是,请记住,在考虑绩效时,所有假设都必须通过衡量来支持。在这种情况下,我认为这两个函数之间没有任何明显的区别。