variadic template 'ambiguous call to overloaded function' seems a false error

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'

>Solution :

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...>();
}

Leave a Reply