C ++标准库是否包含任何生成类似列表的可迭代范围的机制,该范围使用注入的生成器函数来返回每个位置的值?即可以提供类似于C#yield return
或F#' yield
列表推导的行为的东西?理想的是:
hypothetical_generator_list<size_t> l([](size_t index) { return index * 2; });
assert(l[4] == 8);
assert(*(l.begin() + 1000000000) == 2000000000);
动机:我想在数千亿(单调递增)值的空间内进行二分搜索。但是std::lower_bound
想要迭代器,并且将所有值都放在vector
之类的内容中是完全不可能的。但是,我可以轻松编写一个函数,在给定索引的情况下,执行一些计算并返回该索引处的值。
hypothetical_generator_list<size_t> c([](size_t index) { return index * 2; });
auto itFound = std::lower_bound(l.begin(), l.begin() + 100000000000, 6000);
assert(itFound - l.begin() == 3000);
我可以编写自己的自定义迭代器,但与将一个简单的lambda传递给构造函数相比,这似乎有很多工作要做。当然,我可以自己编写二进制搜索(但那有什么乐趣?)。这些是唯一的选择吗?
对于后代,我在这个主题上找到了几个链接:
Equivalent C++ to Python generator pattern
http://www.sirver.net/blog/2011/08/19/generators-in-c++/
但似乎答案是没有办法做到这一点比仅仅编写二进制搜索更简单。
答案 0 :(得分:3)
扫描范围时,算法不会为您提供索引。您可以使用boost.Iterator(或Boost.range)来帮助您编写迭代器(例如[boost::iterator_facade][1]
或[boost::function_input_iterator][2]
)
答案 1 :(得分:0)
它可能有用
template<int X >
class ListGenerator
{
public:
int operator[](int Y){ return X*Y;}
};
int main()
{
ListGenerator<5> lg;
cout<<lg[5]<<endl;
return 0;
}
您可以修改模板参数列表,以根据需要添加。
答案 2 :(得分:0)
这样的东西?
std::size_t index = 0;
std::generate_n(std::back_inserter(list), count, [&index]
{
return index++ * 2;
});
这里我们用生成器函数(lambda)中的count元素填充列表。