我在c ++中编写了懒惰的评估流,但是有一些问题。 这是stream.h:
#ifndef STREAM_H
#define STREAM_H
#include <functional>
#include <cassert>
#include <list>
#include <exception>
template <typename T>
class Stream {
public:
Stream(): isEmpty_(true) {}
Stream(const T& val):
head_(val),
tail_([]() -> Stream<T> { return Stream<T>(); }),
isEmpty_(false) {}
Stream(const T& val, const std::function<Stream<T>()>& tail):
head_(val),
tail_(tail),
isEmpty_(false) {}
Stream<T> tail() {
if (isEmpty_)
return Stream<T>();
return tail_();
}
T get(int idx) {
assert(idx >= 0);
if (isEmpty_)
throw std::runtime_error("out of range");
if (idx == 0)
return head_;
return tail().get(idx - 1);
}
Stream<T> take(int n) {
if ((n == 0) || isEmpty_)
return Stream<T>();
return Stream<T>(head_, [this, n]() -> Stream<T> {
return tail().take(n - 1);
});
}
private:
T head_;
std::function<Stream<T>()> tail_;
bool isEmpty_;
};
template <typename T>
Stream<T> fromList(std::list<T> lst) {
T head = lst.front();
lst.pop_front();
return Stream<T>(head, [=]() -> Stream<T> {
return fromList(lst);
});
}
#endif
这是测试文件:
#include "stream.h"
#include <iostream>
using namespace std;
int main() {
std::list<int> lst{1, 2, 3, 4, 5};
Stream<int> s = fromList(lst);
Stream<int> s1 = s.take(4);
for (int i = 0; i < 4; ++i)
cout << s1.get(i) << endl;
}
编译运行后,崩溃,我无法理解原因,调试信息如下:
(gdb) run
Starting program: /home/lbqds/Desktop/pro/cpp/ts
1
2
Program received signal SIGSEGV, Segmentation fault.
0x00007fffffffd6b8 in ?? ()
(gdb) bt
#0 0x00007fffffffd6b8 in ?? ()
#1 0x00000000004031cd in std::function<Stream<int> ()>::operator()() const (this=0x7fffffffd650)
at /usr/bin/../lib/gcc/x86_64-redhat-linux/6.1.1/../../../../include/c++/6.1.1/functional:2136
#2 0x000000000040316b in Stream<int>::tail (this=0x7fffffffd648) at ./stream.h:27
#3 0x0000000000403091 in Stream<int>::take(int)::{lambda()#1}::operator()() const (this=0x7fffffffd750) at ./stream.h:43
#4 0x0000000000402f2f in std::_Function_handler<Stream<int> (), Stream<int>::take(int)::{lambda()#1}>::_M_invoke(std::_Any_data const&) (
__functor=...) at /usr/bin/../lib/gcc/x86_64-redhat-linux/6.1.1/../../../../include/c++/6.1.1/functional:1725
#5 0x00000000004031cd in std::function<Stream<int> ()>::operator()() const (this=0x7fffffffd750)
at /usr/bin/../lib/gcc/x86_64-redhat-linux/6.1.1/../../../../include/c++/6.1.1/functional:2136
#6 0x000000000040316b in Stream<int>::tail (this=0x7fffffffd748) at ./stream.h:27
#7 0x00000000004015ac in Stream<int>::get (this=0x7fffffffd748, idx=1) at ./stream.h:36
#8 0x00000000004015bc in Stream<int>::get (this=0x7fffffffd7e0, idx=2) at ./stream.h:36
#9 0x0000000000401084 in main () at test.cc:10
(gdb)
我使用fedora24 64bit,clang版本3.8.0,非常感谢。