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;解? (它可能会推广到各种其他适配器。)
答案 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)
即可。 :)这种方法的缺点是它没有保留,所以有性能命中。