Search code examples
c++c++11templatesoverloadingvariadic-templates

How to disambiguate overloaded template functions?


There is a problem with the following code. While 1 part is OK, the problem is with the 2nd part of the main(). On compilation, an ambiguous error message is displayed. How can I change the code to resolve the ambiguity?

template<typename Arg> void func(Arg arg) 
{  
    arg();
}
template<typename Arg, typename... Args> void func(Arg arg, Args... args) 
{  
    func(args...);
    arg();
}
template<typename Container> void func(Container & c) 
{
    for (typename Container::reverse_iterator i = c.rbegin(); i != c.rend(); ++i ) 
    { 
        (*i)();
    } 
}

void f()
{
    std::cout << "+" ;
}

int main()
{
    //1
    func(f,f,f);

    //2    
    std::vector<std::function<void()> > v{f,f};
    func(v);
}

Link to code: http://cpp.sh/3wxrc


Solution

  • How can I change the code to resolve the ambiguity?

    Maybe using template-template ?

    template <template <typename ...> class Cont, typename ... Ts>
    void func (Cont<Ts...> & c) 
    {
        for (typename Cont<Ts...>::reverse_iterator i = c.rbegin(); i != c.rend(); ++i ) 
        { 
            (*i)();
        } 
    }
    

    Deleting the func() Container based version, obviously.

    Simply defining a template parameter Container, doen't make it different from a generic Arg template parameter.

    I know that you use typename Cont<Ts...>::reverse_iterator inside the function. But the compiler has to choose the right overloading according the function signature, not according the body of the functions.

    Using a Cont<Ts...> parameter, you have something more specialized.