在C ++中实现延迟评估流

时间:2016-08-19 14:13:47

标签: c++

我在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,非常感谢。

0 个答案:

没有答案