Thread: unresolved overloaded function

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445

    unresolved overloaded function

    in C++11, let's say I have some code like this:

    Code:
    template<typename Func>
    auto Wrapper(Func func) -> decltype(func())
    {
        return func();
    }
    
    template<typename Func, typename... Args>
    auto Wrapper(Func func, Args... args) -> decltype(func(args...))
    {
        return func(args...);
    }
    
    void foo(int x, std::string y)
    {
    
    }
    
    int foo()
    {
        return 3;
    }
    
    void bar()
    {
        Wrapper(foo, 3, "foo");
        int x = Wrapper(foo);
    }
    if I change the name of one of the foo() functions, it compiles without error, but if both functions are named foo, the compiler gives me the following errors:

    Code:
    In function 'void bar()':
    error: no matching function for call to 'Wrapper(<unresolved overloaded function type>, int, const char [4])'
    note: candidates are:
    note: template<class Func> decltype (func()) Wrapper(Func)
    note: template<class Func, class ... Args> decltype (func(Wrapper::args ...)) Wrapper(Func, Args ...)
    error: no matching function for call to 'Wrapper(<unresolved overloaded function type>)'
    note: candidates are:
    note: template<class Func> decltype (func()) Wrapper(Func)
    note: template<class Func, class ... Args> decltype (func(Wrapper::args ...)) Wrapper(Func, Args ...)
    is there a way to use overloaded functions with this wrapper? if so, how do I need to qualify the function names so that the compiler knows I want the one with two parameters or the one with no parameters?

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You can tell the compiler the type of the function pointer corresponding to the foo you wish to pass along:

    Code:
    void bar()
    {
        Wrapper<void (*)(int, std::string)>(&foo, 3, "foo");
        int x = Wrapper<int (*)()>(&foo);
    }
    This works for me in VS2012.

    The problem is essentially with how template deduction works. The compiler will try to match the type of what you pass in to the template parameters, but never goes further.
    Since foo has two different signatures and the only way to tell them apart is the return type, you are going to get a compile error.
    Last edited by Elysia; 12-05-2012 at 04:57 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Also note that if you're getting into this situation due to things from different places having the same name, that you can simply wrap one or the other inside a namespace. In fact I've seen a namespace declaration directly around a #include to prevent this problem when it came from third-party code.
    Last edited by iMalc; 12-06-2012 at 12:52 AM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The non-variadic Wrapper function, by the way, is not necessary. The variadic version can instantiate to the same thing simply by using an empty parameter pack.
    Also, may I suggest (assuming that you didn't just simplify that part away in your reduced example) that you use perfect forwarding syntax for the wrapper?
    Code:
    template<typename Func, typename... Args>
    auto Wrapper(Func func, Args&&... args) -> decltype(func(std::forward<Args>(args)...))
    {
        return func(std::forward<Args>(args)...);
    }
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    I honestly didn't even know that it could be done that way. I'll keep that in mind in the future.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Overloaded function!
    By Coca cola in forum C++ Programming
    Replies: 3
    Last Post: 03-06-2011, 04:05 AM
  2. unresolve overloaded function
    By nimitzhunter in forum C++ Programming
    Replies: 2
    Last Post: 01-15-2011, 09:19 PM
  3. Overloaded Operator Causes Unresolved External Symbol
    By mikeman118 in forum C++ Programming
    Replies: 11
    Last Post: 03-03-2008, 04:40 PM
  4. is push_back() a overloaded function ?
    By blue_gene in forum C++ Programming
    Replies: 22
    Last Post: 05-02-2004, 03:14 AM
  5. what's an overloaded function ?
    By Nutshell in forum C Programming
    Replies: 5
    Last Post: 01-10-2002, 11:39 AM