Khu*_*hid 4 c++ containers iterator stl-algorithm c++11
我的问题很简单,参见示例:
std::array<int,6> a = {{0,1,2,3,4,5}}; // -- given container.
auto F = []( int i ) { return i*i; }; // -- given function.
std::vector<int> v; // need create
// my solution:
v.reserve( a.size () );
for( std::size_t i = 0; i < a.size(); ++i )
v.push_back( F(a[i]) );
// but I need something like
std::vector<int>v( a.begin(), a.end(), <|applying each element to F|> );
Run Code Online (Sandbox Code Playgroud)
我可以创建上面的容器,而不是显式调用reserve和任何重新分配吗?
编辑:
标准算法std::transform
不正是这样!
std::vector<int> v(a.size());
std::transform(
std::begin(a), std::end(a),
std::begin(v),
F
);
Run Code Online (Sandbox Code Playgroud)
std::back_inserter
如果您愿意,可以从空向量开始并使用:
std::vector<int> v;
std::transform(
std::begin(a), std::end(a),
std::back_inserter(v),
F
);
Run Code Online (Sandbox Code Playgroud)
但是,如果你这样做,你将面临不必要的重新分配(除非你是reserve
第一次,就像你原来的尝试一样).您可以自己决定您的优先级.
#include <algorithm> // std::transform
#include <iterator> // std::back_inserter
....
transform(a.begin(), a.end(), back_inserter(v), F);
Run Code Online (Sandbox Code Playgroud)
您可能需要先拨打电话v.reserve(asize())
以避免重新分配.
另一种解决方案是使用boost::transform_iterator
. 好处是您可以将迭代器传递给容器构造函数。与使用std::back_inserter
或必须调用reserve
或resize
在目的地时相比,这避免了内存重新分配。全部都在一个声明中:
std::vector<int> result(
boost::make_transform_iterator(std::begin(a), F)
, boost::make_transform_iterator(std::end(a), F)
);
Run Code Online (Sandbox Code Playgroud)
不过,您可以实现更简洁的语法,如下所示:
std::vector<int> result(transform_range(a, F));
Run Code Online (Sandbox Code Playgroud)
transform_range
执行:
template<class Iterator>
struct AutoSequence
{
Iterator const beg_, end_;
template<class T>
operator std::vector<T>() const {
return {beg_, end_};
}
};
template<class Function, class InSeq>
auto transform_range(InSeq const& in) -> AutoSequence<decltype(boost::make_transform_iterator<Function>(in.begin()))> {
return {
boost::make_transform_iterator<Function>(std::begin(in))
, boost::make_transform_iterator<Function>(std::end(in))
};
}
template<class Function, class InSeq>
auto transform_range(InSeq const& in, Function&& f) -> AutoSequence<decltype(boost::make_transform_iterator(in.begin(), f))> {
return {
boost::make_transform_iterator(std::begin(in), f)
, boost::make_transform_iterator(std::end(in), f)
};
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
135 次 |
最近记录: |