一行std :: vector ctor来自映射另一个向量?

时间:2012-12-13 21:07:24

标签: c++ stl c++11 iterator

C ++ 11

最后两个行应该有一行版本。

        typedef std::pair<T1, T2> impl_node;
        std::vector<impl_node> impl;
        /* do stuff with impl */
        std::vector<T1> retval(impl.size());
        std::transform(impl.cbegin(), impl.cend(), retval.begin(),
                         [](const impl_node& in) { return *in.first; });

我尝试编写某种自定义迭代器适配器,并且类型变得毛茸茸。什么是&#34;对&#34;解? (它可能会推广到各种其他适配器。)

4 个答案:

答案 0 :(得分:3)

这仍然是两行,但输入较少(两种意义上):

std::vector<T1> retval(impl.size());
for (const auto& p : impl) retval.push_back(p.first); 

实际上,现在我看一下,我更喜欢三行:

std::vector<T1> retval;
retval.reserve(impl.size());
for (const auto& p : impl) retval.push_back(p.first); 

(编辑删除移动,因为没有证据表明它是合适的)

答案 1 :(得分:0)

我不知道如何仅使用C ++ 11中的标准STL在一行中完成此操作,而不首先编写至少一个(模板化的)辅助函数。

您可能正在寻找一个概念,其中2个迭代器成为一个对象,C ++开始支持类似于.NET中的LINQ扩展方法的行为: http://www.boost.org/doc/libs/1_52_0/libs/range/doc/html/index.html

答案 2 :(得分:0)

使用插入迭代器,您可以获得至少一半的内容。

分配vector而不指定大小

std::vector<T1> retval;

...然后使用back_inserter(来自#include <iterator>)填充它:

std::transform(impl.cbegin(), impl.cend(), back_inserter(retval),[](const impl_node& in) { return *in.first; });

答案 3 :(得分:0)

好吧,我们可以从这开始:

template<typename Output, typename Input, typename Transformation>
auto transform( Input const& input, Transformation t )->Output {
  Output retval;
  retval.reserve(input.size());
  using std::cbegin; using std::cend;
  std::transform(cbegin(input), cend(input), std::back_inserter(retval));
  return retval;
}

然后做到这样的事情:

namespace aux{
  using std::cbegin;
  template<typename T>
  auto adl_cbegin( T&& t )->decltype(cbegin(std::forward(t)));
}
template<typename Input, typename Transformation>
auto transform_vec( Input const& input, Transformation t )->
    std::vector<typename std::remove_ref<decltype(t(*adl_cbegin(input)))>::type>
{
  typedef std::vector<typename std::remove_ref<decltype(t(*adl_cbegin(input)))>::type> Output;
  Output retval;
//      retval.reserve(input.size()); -- need a way to do this if Input has an easy way to get size.  Too lazy to bother right now.
  using std::cbegin; using std::cend;
  std::transform(cbegin(input), cend(input), std::back_inserter(retval));
  return retval;
}

注意:这需要任何可迭代的(向量,数组,迭代器对)并产生一个 并且,从那里升级到在输入范围上生成std::pair boost::transform_iterator,因此我们可以将生成的转换插入到任意容器中,如果我们实际取消引用,我们只进行转换工作迭代器。

或者,您知道,只需直接使用std::back_inserter(input)即可。 :)这种方法的缺点是它没有保留,所以有性能命中。