Помимо добавления соединителя JDBC MySQL убедитесь, что context.xml (если он не распакован в папке webapps Tomcat) с вашими определениями соединений с БД включены в каталог Tomcats conf.
С помощью лямбда-выражения привязанные переменные захватываются во время объявления .
Этот пример будет очень ясен: https: // ideone. com / Ly38P
std::function<int()> dowork()
{
int answer = 42;
auto lambda = [answer] () { return answer; };
// can do what we want
answer = 666;
return lambda;
}
int main()
{
auto ll = dowork();
return ll(); // 42
}
Ясно, что захват должен происходить перед вызовом, так как захватываемые переменные даже не существуют (не в масштаб, ни в жизни) больше в более позднее время.
Он связан во время создания. Рассмотрим:
#include <functional>
#include <iostream>
std::function<int(int)> foo;
void sub()
{
int a = 42;
foo = [a](int x) -> int { return x + a; };
}
int main()
{
sub();
int abc = 54;
abc = foo(abc); // Note a no longer exists here... but it was captured by
// value, so the caller shouldn't have to care here...
std::cout << abc; //96
}
Здесь нет функции a
, когда функция вызывается - компилятор не сможет вернуться и обновить его. Если вы передадите a
по ссылке, то у вас есть неопределенное поведение. Но если вы пройдете по значению, любой разумный программист ожидает, что это сработает.
Да, у него есть для захвата по значению в точке, потому что иначе вы могли бы попытаться захватить переменную (например, по ссылке), которая больше не существует, когда функция лямбда / функция действительно вызывается.
Стандарт поддерживает захват как по значению И по ссылке, так и для обоих возможных вариантов использования. Если вы скажете компилятору зафиксировать по значению, он будет захвачен в точке создания лямбда. Если вы попросите захватить по ссылке, он будет захватывать ссылку на переменную, которая затем будет использоваться в точке, на которой вызывается лямбда (требуя, конечно, чтобы ссылочная переменная все еще существовала в точке вызов выполнен).
Я думаю, вы путаете механизм захвата с механизмом передачи переменной. Они не то же самое, даже если они несут какое-то поверхностное сходство друг с другом. Если вам нужно текущее значение переменной внутри лямбда-выражения, запишите его по ссылке (хотя, конечно, эта ссылка привязана к определенной переменной в точке, объявленной лямбдой).
Когда вы «захватить» переменную, вы создаете нечто вроде закрытия. А замыкания всегда статичны (т. Е. «Захват» происходит в точке объявления). Люди, знакомые с понятием лямбда-выражения, найдут лямбда-выражения C ++ очень странными и запутанными, если бы это было иначе. Добавление совершенно новой функции на язык программирования, отличный от той же функции на других языках программирования, каким-то значительным образом сделало бы C ++ еще более запутанным и трудным для понимания, чем это уже есть. Кроме того, все остальное на C ++ статически ограничено, поэтому добавление некоторого элемента динамического охвата будет очень странным по этой причине.
Наконец, если захват всегда происходит по ссылке, то это означает, что лямбда только действительны, если фрейм стека действителен. Либо вам придется добавлять мусорные сборные кадры стека к C ++ (с огромным успехом и много криками от людей, которые зависят от того, что стек в значительной степени соприкасается), или вы в конечном итоге создадите еще одну особенность, когда было бы тривиально легко взорвать ваш но с базукой случайно, поскольку фрейм стека, на который ссылается выражение лямбда, выйдет за рамки, и вы в основном создадите много невидимых возможностей для возврата локальных переменных по ссылке.
function
в точке возврата, используя конструктор копирования шаблонаfunction
, который управляет тиканием стирания стилей и выделяет вызываемую копию в куче. – v.oddou 20 June 2016 в 10:16