This is a stripped down version of my program to illustrate the issue:
#include <functional>
#include <iostream>
template<class T>
class Piped {
public:
typedef T value_type;
};
template<class P1, class P2, class T>
class PipeConnector : public Piped<T> {
public:
PipeConnector(const P1 &p1, const P2 &p2)
: m_1(p1), m_2(p2) { }
bool run(const T &element) const {
return m_1.run(element) || m_2.run(element);
}
private:
const P1 &m_1;
const P2 &m_2;
};
template<class T>
class NullOp : public Piped<T> {
public:
bool run(const T&) const {
return false;
}
};
template<class T, class Functor>
class FunctionOp : public Piped<T> {
public:
FunctionOp(Functor f1)
: m_1(f1) { }
bool run(const T &element) const {
return m_1(element);
}
private:
std::function<bool(T)> m_1;
};
template<class P1, class Functor>
auto operator|(const P1 &p1, const Functor &f2) {
return PipeConnector<P1,
FunctionOp<typename P1::value_type, std::function<bool(typename P1::value_type)>>, typename P1::value_type>(
p1, FunctionOp<typename P1::value_type, std::function<bool(typename P1::value_type)>>(f2));
}
int main() {
auto p = NullOp<int>() | [](int x) -> bool { if (x < 10) { return true;} return false; };
std::cout << p.run(20) << std::endl;
return 0;
}
Compiling this program using g++ / clang++ -std=c++14 leads to a segfault. Adding -O3 to it, makes it run without a segfault.
When changing the PipeConnector to not store const references but storing copies, this works. I assume the problem is some lambda scope issue, but I don't understand what goes wrong. -O3 seems to elide the problem? Could you explain the issue to me, please?