Этот ответ является ответом на комментарий выше и не работает с VisualStudio 2008, но должен быть предпочтительнее с более поздними компиляторами.
Между тем вам больше не нужно использовать указатель void и нет необходимости в усилении, так как доступны std::bind
и std::function
. Преимущество одного (по сравнению с указателями void) - это безопасность типа, поскольку тип возврата и аргументы явно указаны с помощью std::function
:
// std::function
void Init(std::function f);
Затем вы можете создать функцию указатель с std::bind
и передать его Init:
auto cLoggersInfraInstance = CLoggersInfra();
auto callback = std::bind(&CLoggersInfra::RedundencyManagerCallBack, cLoggersInfraInstance);
Init(callback);
Полный пример для использования std::bind
с членами, статическими членами и не-членными функциями:
#include
#include
#include
class RedundencyManager // incl. Typo ;-)
{
public:
// std::function
std::string Init(std::function f)
{
return f();
}
};
class CLoggersInfra
{
private:
std::string member = "Hello from non static member callback!";
public:
static std::string RedundencyManagerCallBack()
{
return "Hello from static member callback!";
}
std::string NonStaticRedundencyManagerCallBack()
{
return member;
}
};
std::string NonMemberCallBack()
{
return "Hello from non member function!";
}
int main()
{
auto instance = RedundencyManager();
auto callback1 = std::bind(&NonMemberCallBack);
std::cout << instance.Init(callback1) << "\n";
// Similar to non member function.
auto callback2 = std::bind(&CLoggersInfra::RedundencyManagerCallBack);
std::cout << instance.Init(callback2) << "\n";
// Class instance is passed to std::bind as second argument.
// (heed that I call the constructor of CLoggersInfra)
auto callback3 = std::bind(&CLoggersInfra::NonStaticRedundencyManagerCallBack,
CLoggersInfra());
std::cout << instance.Init(callback3) << "\n";
}
Возможный выход:
Hello from non member function!
Hello from static member callback!
Hello from non static member callback!
Кроме того, используя std::placeholders
, вы можете динамически передавать аргументы для обратного вызова (например, это позволяет использовать return f("MyString");
в Init
, если f имеет строковый параметр).
Вы можете скрыть navbar-brand
с помощью .css
, установив {display:none}
. Для этого вам нужно немного адаптировать свой интерфейс. Поскольку вы используете navbarPage
, вам нужно добавить функцию tagList
. Если вы не заключите его в список тегов, блестящий подумает, что вы хотите создать новый tabPanel
, и появится вкладка-призрак. Более подробная информация здесь.
Рабочий пример:
ui <- shinyUI(
tagList(tags$head(tags$style(type = 'text/css','.navbar-brand{display:none;}')),
navbarPage(
'', collapsible=TRUE,
tabPanel("panel 01", 'some text'), tabPanel("panel 02"), tabPanel("panel 03"),
tabPanel("panel 04"), tabPanel("panel 05"), tabPanel("panel 06"),
tabPanel("panel 07"), tabPanel("panel 08"), tabPanel("panel 09"),
tabPanel("panel 10"), tabPanel("panel 11"), tabPanel("panel 12")
)))
server <- function(input, output){}
shinyApp(ui=ui, server=server)