I try to write a template function to initialize given systems and run the app and at the end run shutdown function on initialized systems.
This code should work in my eye and intellisense doesn't give any error but compiler:
1>C:\VisualStudio\DirectApp\AppMain.cpp(32,2): error C2668: 'initialize_these': ambiguous call to overloaded function
1>C:\VisualStudio\DirectApp\AppMain.cpp(28,13): message : could be 'void initialize_these<WindowManager,>(void)'
1>C:\VisualStudio\DirectApp\AppMain.cpp(18,13): message : or 'void initialize_these<WindowManager>(void)'
1>C:\VisualStudio\DirectApp\AppMain.cpp(29,1): message : while trying to match the argument list '()'
1>C:\VisualStudio\DirectApp\AppMain.cpp(29): message : see reference to function template instantiation 'void initialize_these<Log,WindowManager>(void)' being compiled
1>C:\VisualStudio\DirectApp\AppMain.cpp(29): message : see reference to function template instantiation 'void initialize_these<Heap,Log,WindowManager>(void)' being compiled
1>C:\VisualStudio\DirectApp\AppMain.cpp(29): message : see reference to function template instantiation 'void initialize_these<SystemInfo,Heap,Log,WindowManager>(void)' being compiled
1>C:\VisualStudio\DirectApp\AppMain.cpp(45): message : see reference to function template instantiation 'void initialize_these<Sdl,SystemInfo,Heap,Log,WindowManager>(void)' being compiled
The Code:
#include "pch.h"
#include "AppMain.h"
#include "AppRun.h"
#include "Dummy.h"
#include "Heap.h"
#include "Log.h"
#include "Sdl.h"
#include "SystemInfo.h"
#include "WindowManager.h"
static void initialize_these()
{
AppMain::run<AppRun>();
}
template<class Type = Dummy>
static void initialize_these()
{
if (AppMain::initialize<Type>()) { return; }
initialize_these();
AppMain::shutdown<Type>();
}
template<class First, class... Rest>
static void initialize_these()
{
if (AppMain::initialize<First>()) { return; }
initialize_these<Rest...>();
AppMain::shutdown<First>();
}
void AppMain::app_main()
{
initialize_these<
Sdl,
SystemInfo,
Heap,
Log,
WindowManager
>();
}
Hope the code be clear enough.
Oh, btw. those AppMain::initialize<>()
calls will give true if initialization failed.
I check different part of this code. It seems to me everything is alright but the variadic templates of static void initialize_these()
function.
Edit: I remove
template<class Type = Dummy>
static void initialize_these()
{
if (AppMain::initialize<Type>()) { return; }
initialize_these();
AppMain::shutdown<Type>();
}
Compiler error:
1>C:\VisualStudio\DirectApp\AppMain.cpp(22,2): error C2672: 'initialize_these': no matching overloaded function found
1>C:\VisualStudio\DirectApp\AppMain.cpp(19): message : see reference to function template instantiation 'void initialize_these<WindowManager,>(void)' being compiled
1>C:\VisualStudio\DirectApp\AppMain.cpp(19): message : see reference to function template instantiation 'void initialize_these<Log,WindowManager>(void)' being compiled
1>C:\VisualStudio\DirectApp\AppMain.cpp(19): message : see reference to function template instantiation 'void initialize_these<Heap,Log,WindowManager>(void)' being compiled
1>C:\VisualStudio\DirectApp\AppMain.cpp(19): message : see reference to function template instantiation 'void initialize_these<SystemInfo,Heap,Log,WindowManager>(void)' being compiled
1>C:\VisualStudio\DirectApp\AppMain.cpp(35): message : see reference to function template instantiation 'void initialize_these<Sdl,SystemInfo,Heap,Log,WindowManager>(void)' being compiled
1>C:\VisualStudio\DirectApp\AppMain.cpp(22,2): error C2783: 'void initialize_these(void)': could not deduce template argument for 'First'
1>C:\VisualStudio\DirectApp\AppMain.cpp(18): message : see declaration of 'initialize_these'
CodePudding user response:
the Rest
can be empty, so both are valid.
you can make the variadic one accept 2 or more argument
template<class Type>
static void f(){
// do something with Type
}
template<class First, class Second, class... Rest>
static void f(){
// do something with First
f<Second,Rest...>();
}
CodePudding user response:
with c 17
if constexpr
you can also write it like this
template<class Type, class... Rest>
static void f(){
// do something with Type
if constexpr(sizeof...(Rest))
f<Rest...>();
}