来自一个Python
世界,我觉得这个功能std::iota
非常有限.为什么界面限制为不接受UnaryFunction
?
比如我可以转换
>>> x = range(0, 10)
成
std::vectorx(10); std::iota(std::begin(x), std::end(x), 0);
但是如何做到:
>>> x = range(0,20,2)
甚至
>>> x = range(10,0,-1)
我知道编写一个这样的函数或使用Boost是微不足道的,但我认为C++委员会必须谨慎选择这个设计.很明显,我错过了C++ 11中的一些东西.
怎么样std::generate
?
int n = -2; std::generate(x.begin(), x.end(), [&n]{ return n+=2; }); int n = 10; std::generate(x.begin(), x.end(), [&n]{ return n--;})
但是如何做到:
x = range(0,20,2)
或者std::generate()
(参见其他答案),您可以提供自己的一元函数std::iota()
,只需要调用它operator++()
:
#include#include #include #include template struct IotaWrapper { typedef T type; typedef std::function IncrFunction; type value; IncrFunction incrFunction; IotaWrapper() = delete; IotaWrapper(const type& n, const IncrFunction& incrFunction) : value(n), incrFunction(incrFunction) {}; operator type() { return value; } IotaWrapper& operator++() { value = incrFunction(value); return *this; } }; int main() { IotaWrapper n(0, [](const int& n){ return n+2; }); std::vector v(10); std::iota(v.begin(), v.end(), n); for (auto i : v) std::cout << i << ' '; std::cout << std::endl; }
输出:0 2 4 6 8 10 12 14 16 18
Demo
以下是一个如何实现的想法Range()
:
struct Range { templatestd::vector operator()(const Value& first, const Value& last, const Incr& increment) { IotaWrapper iota(first, [=](const int& n){ return n+increment; }); std::vector result((last - first) / increment); std::iota(result.begin(), result.end(), iota); return result; } };
Demo