【问题标题】:How to copy references of elements of one vector to another vector?如何将一个向量的元素的引用复制到另一个向量?
【发布时间】:2017-12-11 18:19:24
【问题描述】:

我有一个vector

std::vector<island> sea;

现在我想在另一个vector 中保存指向这个vector 的所有元素的指针。但只是为了个人练习,我想以花哨的 C++ 风格执行此操作,所以我输入的是 std::vector&lt;const island*&gt; p_sea,而不是:

std::vector<std::reference_wrapper<const island>> r_sea;

现在我想用引用填充这个新的vector

std::transform(sea.begin(), sea.end(),
               std::back_inserter(r_sea),
               std::cref<island>
);

按照我的理解,从cppreference文章来看,transform的第四个参数应该是一个函数,它接受源范围内元素的const引用并返回目标范围内的元素;这正是std::cref&lt;island&gt; 所做的:它将const island&amp; 作为参数并返回std::reference_wrapper&lt;const island&gt;。所以我相信这应该行得通??

但是,它没有:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>


struct island {
    long long x,y; //coords
};

int main() {
    std::vector<island> sea;
    std::vector<std::reference_wrapper<const island>> r_sea;

    std::transform(sea.begin(), sea.end(),
                   std::back_inserter(r_sea),
                   std::cref<island>
    );

    return 0;
}

这会导致以下编译错误:

prog.cpp: In function ‘int main()’:
prog.cpp:19:5: error: no matching function for call to ‘transform(std::vector<island>::iterator, std::vector<island>::iterator, std::back_insert_iterator<std::vector<std::reference_wrapper<const island> > >, <unresolved overloaded function type>)’
     );
     ^
In file included from /usr/include/c++/6/algorithm:62:0,
                 from prog.cpp:3:
/usr/include/c++/6/bits/stl_algo.h:4166:5: note: candidate: template<class _IIter, class _OIter, class _UnaryOperation> _OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation)
     transform(_InputIterator __first, _InputIterator __last,
     ^~~~~~~~~
/usr/include/c++/6/bits/stl_algo.h:4166:5: note:   template argument deduction/substitution failed:
prog.cpp:19:5: note:   could not resolve address from overloaded function ‘cref<island>’
     );
     ^
In file included from /usr/include/c++/6/algorithm:62:0,
                 from prog.cpp:3:
/usr/include/c++/6/bits/stl_algo.h:4203:5: note: candidate: template<class _IIter1, class _IIter2, class _OIter, class _BinaryOperation> _OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation)
     transform(_InputIterator1 __first1, _InputIterator1 __last1,
     ^~~~~~~~~
/usr/include/c++/6/bits/stl_algo.h:4203:5: note:   template argument deduction/substitution failed:
prog.cpp:19:5: note:   could not resolve address from overloaded function ‘cref<island>’
     );

https://ideone.com/E80WXH

我做错了什么?

...我回到邪恶的 C 指针。

【问题讨论】:

  • 试试std::reference_wrapper&lt;const island&gt;而不是std::reference_wrapper&lt;const island*&gt;
  • @cdhowie 错字;不修复编译错误;正在删除问题中的错字。
  • 你的问题是std::cref 超载了。您需要明确使用哪个重载。
  • @StoryTeller 怎么样?
  • 你为什么不发布你的真实代码?

标签: c++ templates compiler-errors function-object reference-wrapper


【解决方案1】:

std::cref&lt;island&gt; 替换为[](auto&amp;x){return std::cref&lt;island&gt;(x);},假设

中,将auto 替换为island const

cref 有重载,您不能将重载集作为对象传递,因为重载集不是对象。

【讨论】:

    【解决方案2】:

    std::cref 过载。仅仅指定模板参数不足以消除重载之间的歧义。你有两个选择:

    1. 投吧

      static_cast<std::reference_wrapper<const island>(*)(const island&)>(std::cref<island>)
      
    2. 将名称提升为仿函数对象(lambda)。就像@Yakk 提议的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-07
      • 2021-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多