C++ 具有分段错误的函数模板

C++ 具有分段错误的函数模板,c++,c++11,c++14,C++,C++11,C++14,我将拉函数写入链接(读取->通过…->接收器) 模板 自动拉取(T&流){ 返回std::转发(流); } //返回作废/读取 //读取->水槽 //阅读->通读 模板 自动拉取(R&R读取、S&S接收器){ 返回接收器(标准:正向(读取)); } //返回读取 //读取->通过->。。。 模板 自动拉取(R&&read、T&through、Ts&&args){ 返回拉力(通过(std::forward(read)),std::forward(args)…); } read函数,如下所示,提供

我将拉函数写入链接(读取->通过…->接收器)

模板
自动拉取(T&流){
返回std::转发(流);
}
//返回作废/读取
//读取->水槽
//阅读->通读
模板
自动拉取(R&R读取、S&S接收器){
返回接收器(标准:正向(读取));
}
//返回读取
//读取->通过->。。。
模板
自动拉取(R&&read、T&through、Ts&&args){
返回拉力(通过(std::forward(read)),std::forward(args)…);
}
read函数,如下所示,提供一个向量:

template<typename T>
auto values(T &begin, T &end) {
    return [&](bool abort, auto cb) {

        if (end != begin) {
            cb(false, *begin++);
        } else {
            cb(true, *begin);
        }
    };
}
模板
自动值(T&begin、T&end){
返回[&](布尔中止,自动cb){
如果(结束!=开始){
cb(false,*begin++);
}否则{
cb(真,*开始);
}
};
}
通过函数,如下所示:

template<typename T, typename M>
auto Map(M &&mapper) {

    return [&](auto &&read) {
        return [&](bool abort, auto cb) {
            read(abort, [&](bool end, T val) {
                if (end)
                    cb(true, val);
                else
                    cb(false, mapper(val));
            });
        };
    };
}
template<typename T, typename R>
auto log(R &&read) {

    std::function<void(bool, T)> more = [&](bool done, T val) {
        if (!done) {
            cout << val << endl;
            read(false, more);
        }
    };

    read(false, more);
}
模板
自动映射(M&映射器){
返回[&](自动读取(&R)){
返回[&](布尔中止,自动cb){
读取(中止,[&](布尔结束,T值){
若(完)
cb(真,val);
其他的
cb(假,映射器(val));
});
};
};
}
接收器功能如下:

template<typename T, typename M>
auto Map(M &&mapper) {

    return [&](auto &&read) {
        return [&](bool abort, auto cb) {
            read(abort, [&](bool end, T val) {
                if (end)
                    cb(true, val);
                else
                    cb(false, mapper(val));
            });
        };
    };
}
template<typename T, typename R>
auto log(R &&read) {

    std::function<void(bool, T)> more = [&](bool done, T val) {
        if (!done) {
            cout << val << endl;
            read(false, more);
        }
    };

    read(false, more);
}
模板
自动日志(R&&read){
std::function more=[&](bool done,T val){
如果(!完成){

cout我想我已经知道了哪里出了问题。正如前一位用户所评论的,在通过引用捕获超出其范围的lambda时,需要非常谨慎

具体来说,我认为问题出在
Map
函数内部,其中内部lambda通过引用捕获
read
参数。如果使用作用域超过lambda的左值参数调用它,这很好,就像单次调用情况
pull(vals,times2)
times2一样(VAL)
,但在双调用情况下,
pull(VAL,timesTwo,timesTwo)
=>
timesTwo(timesTwo(VAL))
,传递给
timesTwo
外部调用的参数是一个右值,因此
read
引用对象立即挂起


另外一个不相关的问题:在
values
函数中,lambda中的
else
子句将取消对end迭代器的引用。我不相信您依赖于它的返回值,它似乎按照预期工作,但它是未定义的行为。

我想我已经找出了哪里出了问题。正如前一位用户评论的那样d、 在通过引用捕获超出其范围的lambda时,需要非常谨慎

具体来说,我认为问题出在
Map
函数内部,其中内部lambda通过引用捕获
read
参数。如果使用作用域超过lambda的左值参数调用它,这很好,就像单次调用情况
pull(vals,times2)
times2一样(VAL)
,但在双调用情况下,
pull(VAL,timesTwo,timesTwo)
=>
timesTwo(timesTwo(VAL))
,传递给
timesTwo
外部调用的参数是一个右值,因此
read
引用对象立即挂起


另外一个不相关的问题:在
values
函数中,lambda中的
else
子句将取消对end迭代器的引用。我不相信您依赖于它的返回值,它似乎按照预期工作,但它是未定义的行为。

lambda通过返回或使用捕获e的std::函数来逃避其作用域通过引用进行验证通常是一个危险信号。肯定还有另一个问题我还没有解决,但有一个问题是你在
values
中的lambda中的
else
子句中取消了对
end
迭代器的引用。SegFault意味着你耗尽了你的内存!我早些时候被骂过!但这才是真正的问题。我希望这有帮助!通过return或使用std::函数通过引用捕获所有内容而超出其作用域的Lambda通常是一个红色标志。肯定还有另一个问题我还没有解决,但有一个问题是您在
值中的Lambda的
else
子句中取消引用
end
迭代器>.SegFault意味着你的记忆力被破坏了!我之前被骂过!但这才是真正的问题。我希望这会有所帮助!我也不确定
vals
是否在一次使用后就被消耗掉了,因为
begin
迭代器是通过引用捕获并递增的,直到它等于
end
。我想你是这样想的是的,bug如何纠正它,你能帮我吗?@langyu你在问我发现的三个bug中的哪一个?当然你可以自己解决其中一些问题。case
pull(vals,times2,times2)=>times2(times2(vals))
读取
参考对象立即悬空->我想修复这个错误,但我不知道如何修复,我已经花了3天时间…你能帮我吗?@langyu让你所有的lambda捕获都显式(没有
[&]
-列出所有你想要捕获的变量),仔细决定哪些应该通过引用,哪些应该通过值。特别是,
read
需要通过该特定lambda中的值来捕获,以避免此segdault,但是还有一些仅在特定用例中工作,但通常不能保证。我也不确定
vals
是否是故意的基本上是在一次使用后消耗的,因为
开始
迭代器通过引用捕获并递增,直到它等于
结束
。我想你是对的,bug如何纠正它,你能帮我吗?@langyu我发现的三个bug中,你问的是哪一个?当然你可以自己解决其中的一些.case
pull(VAL,timesTwo,timesTwo)=>timesTwo(timesTwo(VAL))
read
引用对象立即悬空->我想修复此错误,但我没有