[英]Dereferencing a pointer while passing to a reference expecting function creates a copy, why?
考虑一个简单的例子
template<class InputIterator,class InputIterator2, class OutputIterT, class Function, class T2>
OutputIterT foo(InputIterator first, InputIterator2 last, OutputIterT result, Function fn, const T2& x)
{
while (first!=last) {
*result=fn(*first,x);
++first;
}
return result;
}
传递的函数fn在哪里
template<class T, class V>
T fn(const T& a, const V& b) {
return std::make_pair(a.first, a.second *b);
}
当我使用此代码并检查是否调用了构造函数时,我看到在每次调用fn(* first,x)时,都会调用复制构造函数。 我觉得这很难理解,因为function参数是一个参考。 请注意,正在使用的迭代器是映射迭代器。 为了避免不必要的复制,我将代码更改为直接接受迭代器(fn函数),因此现在的行是
*result=fn(first,x);
而fn是
template<class Iter, class V>
T fn(Iter a, const V& b) {
return std::make_pair(a->first, a->second *b);
}
为什么在第一种情况下使用fn调用创建副本? 什么时候会发生? 即使function参数是const引用,为什么也会发生呢? 感谢您帮助我理解。
要澄清的是,
(*first).second
在进入函数fn之前被调用。
@IgorTandetnik在下面的评论中提供了正确的答案,而@SebastianRedl提供了进一步的解释。
类型的地图对象
map<Key,Value>;
是真的
map<Key const,Value>;
即使程序员没有这样指定(如果省略const)。
现在,在实例化foo函数时,如果您像我一样提供对类型为
pair<Key,Value>
这与地图中包含的对不匹配,即
pair<Key const, Value>
(同样,即使您没有明确指出key应该是const)。 与传递给函数fn一样,这需要进行转换。
谢谢你俩!
我认为该副本是在std::make_pair()
方法中完成的,该方法返回对一个新对象的引用,该对象由两个类T和V的实例组成,这些实例是从a->first
和a->second *b
复制而来的。 否则,修改返回的对中的任何内容也会修改您在fn()
通过引用传递的对象。
编辑:现在您已经提供了更多信息,我认为在执行时会调用(* first).second的副本构造函数: a->second *b
。 由于我不知道您的运算符*如何重载,我想它暗示着一个副本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.