Насколько я знаю, это неопределенное поведение.
Проблема в том, что ваш класс регистрирует ссылку
// ..........V reference !!!
const Lambda & _lambda;
аргумента конструктора
Lambda_Expression(const Lambda & l) : _lambda(l) {}
это std::function
using Lambda = std::function<T()>;
Но когда вы вызываете конструктор с помощью лямбды (как в main()
)
auto test_expression = Lambda_Expression<double, std::vector<double>>(lambda);
, вы сохраняете в _lambda
ссылку навременный объект, потому что lambda
не является std::function
, поэтому он создает временный объект типа std::function<double()>
, инициализированный с lambda
.
Итак, проблема:ссылка на временный объект становится висячей ссылкой в конце построения test_expression
, поэтому при вызове test_expression[idx]
вы используете _lambda
, указывающий (потенциально) на мусор.
Я предлагаючтобы избежать подобных проблем, избегая ссылочной части (сделайте _lambda
обычным членом типа std::function
const Lambda _lambda; // <-- no more reference
, чтобы вы скопировали временный объект)
Но если вы действительно хотитечто _lambda
является ссылкой на std::function
, вы должны написать что-то следующим образом
std::function<double()> f{lambda};
auto test_expression = Lambda_Expression<double, std::vector<double>>{f};
Таким образом, конструктор получает ссылку на std::function
объект (f
), который сохранился до его вызова.