如何使用(lambda)函数填充C++容器
How to fill a C++ container using a (lambda) function?
我想用指向对象的指针初始化一个容器。我现在有一个这样的循环:
for(int i=0;i < n;i++) {
container.push_back(new Object());
}
哪个C++操作(即类似于std::transform
(可以替换此循环并用n
新创建的对象初始化容器?
使用std::generate:
constexpr int n = 10;
std::vector<Object*> v1(n);
std::generate(v1.begin(), v1.end(), [](){ return new Object(); });
或std::generate_n:
std::vector<Object*> v2;
v2.reserve(n); // pre-allocate sufficient memory to prevent re-allocations
// (you should have done in original loop approach as well)
std::generate_n(std::back_inserter(v2), n, [] { return new Object(); });
您可以将std::generate_n
和std::back_inserter
与lambda一起使用。
std::generate_n(std::back_inserter(container), n, [] { return new Object(); });
目标是这样的语法:
std::vector<Object*> v1 = generate([](auto&&){ return new Object; }, 10).make_container();
如果我们说要生成10个具有特定lambda的元素,那么我们将创建一个所需类型的容器。
这需要一些样板。首先,一个计算并调用函数的输入迭代器:
template<class F>
struct generator_iterator {
F f;
std::size_t i = 0;
using self=generator_iterator;
friend bool operator==(self const& lhs, self const& rhs){ return lhs.i==rhs.i; }
friend bool operator!=(self const& lhs, self const& rhs){ return lhs.i!=rhs.i; }
using reference=std::result_of_t<F const&(std::size_t const&)>;
using value_type=std::decay_t<reference>;
using difference_type=std::ptrdiff_t;
using pointer=value_type*;
using iterator_category=std::input_iterator_tag;
self& operator++(){++i; return *this;}
self operator++(int){auto tmp=*this; ++*this; return tmp;}
reference operator*()const{ return f(i); }
pointer operator->()const { return std::addressof(f(i)); }
friend difference_type operator-( self const& lhs, self const& rhs ) { return lhs.i-rhs.i; }
self& operator-=( difference_type rhs )& {
i-=rhs;
return *this;
}
self& operator+=( difference_type rhs )& {
i+=rhs;
return *this;
}
friend difference_type operator+( self lhs, difference_type rhs ) {
lhs += rhs;
return lhs;
}
friend difference_type operator-( self lhs, difference_type rhs ) {
lhs -= rhs;
return lhs;
}
};
接下来是一个范围基元,带有.make_container()
方法,可以通过显式或隐式传递类型将范围转换为容器:
template<class It>
struct range_t {
It b, e;
It begin() const { return b; }
It end() const { return e; }
private:
struct container_maker {
range_t const* self;
template<class C>
operator C()&& {
return {self->begin(), self->end()};
}
};
public:
container_maker make_container()const{
return {this};
}
// C is optional
template<class C>
C make_container()const{
return make_container();
}
};
template<class It>
range_t<It> range( It s, It f ) {
return {std::move(s), std::move(f)};
}
然后我们把它们粘在一起:
template<class F>
auto generate( F&& f, std::size_t count ) {
generator_iterator<std::decay_t<F>> e{f, count};
generator_iterator<std::decay_t<F>> b{std::forward<F>(f)};
return range( std::move(b), std::move(e) );
}
并编译:
std::vector<Object*> v1 = generate([](auto&&){ return new Object; }, 10).make_container();
活生生的例子。
相关文章:
- 在c++中用vector填充一个简单的动态数组
- 如何使用用户输入在C++中正确填充2D数组
- 如何找到大小'x'数组是否完全填充,在C++?
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 通过for循环使用用户输入填充列表
- 根据用户输入用字母填充矢量,并将"开始"和"结束"放在四肢
- 如何正确填充在堆上分配的二维数组?
- 将数字转换为填充字符串
- 有没有办法在一行中填充矢量图
- 用C++中的数字和条件填充向量
- 用真值填充矢量
- 使用结构成员指针在C++中填充结构
- 流填充字符的默认定位
- 使用不同算法的 PKCS1v15 填充进行加密 ++ 签名
- C++:使用缓冲区中的数据填充结构
- 如何将零填充的多维数组传递给 C++ 中的函数?
- Cryptopp:获取密码输入的填充字符串
- 填充上编译器生成的复制构造函数之间的不一致
- RcppEigen 模板化函数,用于填充单位法线
- 我想生成许多矩阵并用随机数填充它