C++ 在传递到预期引用函数时取消引用指针会创建副本,为什么?

C++ 在传递到预期引用函数时取消引用指针会创建副本,为什么?,c++,copy-constructor,dereference,C++,Copy Constructor,Dereference,考虑一个简单的例子 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

考虑一个简单的例子

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 Iter, class V>
 T fn(Iter a, const V& b) {
   return std::make_pair(a->first, a->second *b);
}
在输入函数fn之前,正在调用

答复 @IgorTandetnik在下面的评论中给出了正确的答案,@SebastianRedl进一步解释了为什么会发生这种情况

类型的映射对象

map<Key,Value>;
真是

map<Key const,Value>;
如果省略常量,即使程序员没有这样指定它

现在,在实例化foo函数时,如果您像我一样提供pair类型

pair<Key,Value>
这与映射中包含的对不匹配,它们是

pair<Key const, Value>
同样,即使您并没有明确地说key应该是const。这导致在传递到函数fn时需要进行转换


谢谢你们两位

我认为复制是在std::make_pair方法中进行的,该方法返回对新对象的引用,该对象由从a->first和a->second*b复制的类T和V的两个实例组成。否则,修改返回对中的任何内容也会修改在fn中通过引用传递的对象


编辑:现在您已经提供了更多信息,我认为在执行:a->second*b时会调用*first.second的复制构造函数。因为我不知道你的操作符是如何重载的*,我猜它意味着一个副本。

所调用内容的副本构造函数?我建议你展示一下这个看起来很有趣。请添加一个在其当前形式下很难进行推理的。std::make_paira.first,a.second*b将复制a.first,并可能复制a.second和/或b,具体取决于*的含义。fn是否接受std::paira.first,a.second*b?如果在std::map上迭代,*first的类型为std::pair-另一种类型,因此将执行隐式转换。无论模板参数是否为,std::map的键类型都是const。这是因为您无法更改映射中已存在的键,这可能会更改它们的比较方式,从而损坏映射的内部结构。该运算符使用常量referece重载lhs和rhs以及右值引用。在输入fn之前正在调用复制构造函数。
map<Key const,Value>;
pair<Key,Value>
pair<Key const, Value>