Этот ответ должен быть довольно коротким и сладким, чтобы ответить (часть) озаглавленного вопроса. Если вы хотите получить более подробный ответ, объясняющий, почему вы должны их там поместить, пожалуйста, перейдите здесь .
Общее правило для размещения typename
в основном, когда вы используете параметр шаблона, и хотите получить доступ к вложенному typedef
или с использованием псевдонима, например:
template
struct test {
using type = T; // no typename required
using underlying_type = typename T::type // typename required
};
Обратите внимание, что это также относится к метафункциям или вещи, которые также принимают общие параметры шаблона. Однако, если предоставленный параметр шаблона является явным типом, вам не нужно указывать typename
, например:
template
struct test {
// typename required
using type = typename std::conditional::type;
// no typename required
using integer = std::conditional::type;
};
Общие правила добавления определителя template
в основном аналогичны, за исключением они обычно включают шаблонные функции-члены (статические или другие) структуры / класса, которые сами шаблоны, например:
Учитывая эту структуру и функцию:
template
struct test {
template
void get() const {
std::cout << "get\n";
}
};
template
void func(const test& t) {
t.get(); // error
}
Попытка доступа t.get
изнутри функции приведет к ошибке:
main.cpp:13:11: error: expected primary-expression before 'int'
t.get();
^
main.cpp:13:11: error: expected ';' before 'int'
Таким образом, в этом контексте вам понадобится ключевое слово template
заранее и вызвать его так:
t.template get
Таким образом, компилятор будет анализировать это правильно, а не t.get < int
.
Вы могли записать ServletContextListener
, который называет Ваш метод от contextInitialized()
метод. Вы присоединяете слушателя своего веб-приложения в web.xml, например,
<listener>
<listener-class>my.Listener</listener-class>
</listener>
и
package my;
public class Listener implements javax.servlet.ServletContextListener {
public void contextInitialized(ServletContext context) {
MyOtherClass.callMe();
}
}
Строго говоря, это только выполняется однажды на запуске веб-приложения, а не запуске Tomcat, но это может составить то же самое.
Я уверен, что должен быть лучший способ сделать это как часть жизненного цикла контейнера (редактирование: Моток имеет ответ - я задавался вопросом, почему он предлагал SessonListener
, прежде чем я ответил), но Вы могли создать Сервлет, который не имеет никакой другой цели, чем выполнить одноразовые действия, когда сервер запущен:
<servlet>
<description>Does stuff on container startup</description>
<display-name>StartupServlet</display-name>
<servlet-name>StartupServlet</servlet-name>
<servlet-class>com.foo.bar.servlets.StartupServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>