0

Hello what wrong Iam doing here in using variadic templates via string? How to use it properly to achieve the below task?

#include <iostream>
#include<string>

int sum(int a, int b, int c, int d) { return a+b+c+d; }
int strcopy(char* str)   { strcpy(str,"Hello World!!!"); return 1; }

template<typename Func, typename... Args>
auto MainCall(Func func, Args&&... args)-> typename std::result_of<Func(Args...)>::type
{
    return func(std::forward<Args>(args)...);
}

template<typename... funcname, typename... Args>
int CallFunction(std::string const& Func , Args&&... args)
{

    if(!Func.compare("sum"))
    {
        return MainCall(sum, args...);
    }
    else if(!Func.compare("strcopy"))
    {
        return MainCall(strcopy, args...);
    }
    else
    {
        return 0;
    }

}


int _tmain(int argc, _TCHAR* argv[])
{
    char buffer[512];
    cout <<  CallFunction("sum",1,2,3,4) << end1; /* How to properly execute "sum" function by sending string name to variadic function template function??? */
    CallFunction("strcopy",buffer); /* How to properly execute "strcopy" function by sending string name to variadic function template function??? */
    printf("Buffer says = %s" , buffer); /* Should print "Hello World!!!" */
    getchar();
    return 0;
}

I get compiler error like
error C2197: 'int (__cdecl *)(char *)' : too many arguments for Maincall
see reference to class template instantiation 'std::_Result_type<false,_Fty,_V0_t,_V0_t,_V2_t,_V2_t,_V4_t,_V4_t,_V6_t,_V6_t,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>' being compiled

8
  • Please improve your old question, instead of asking the same again. Commented Dec 31, 2014 at 9:35
  • I'm not into C++, maybe it's expected, but I don't see your call to MainCall. Also, try to remove anything until remove anything more makes the bug disappear. i.e does it still happen when you remove the call to the "sum" ? The printf ? getchar()... etc. We only need the strictly necessary code to reproduce your problem. Commented Dec 31, 2014 at 9:38
  • This is totally different question from this... Here I want to know how to use variadic template using string and calling a function. Yes !!! I have asked this question in that post in comments column since I didnt get any answer I posted it has new question. Commented Dec 31, 2014 at 9:40
  • @Lo1234 Well, patience is a gift. Commented Dec 31, 2014 at 9:41
  • @Lo1234 you didn't get any answer on your previous question because your code worked fine. You admitted to using an old compiler which didn't support variadic templates and after upgrading it you were able to successfully run your code. What answer do you expect on that question now? Commented Dec 31, 2014 at 9:45

1 Answer 1

3

The problem is:

When you call:

CallFunction("sum", 1, 2, 3, 4)

The templated function CallFunction is instantiated with funcanme={} (totally useless, you can remove it) and Args={int, int, int, int}. In this function you have a line: MainCall(strcopy, args...); which in this case becomes: MainCall(strcopy, 1, 2, 3, 4) which in turn calls strcopy(1, 2, 3, 4) which is invalid call.

There is no (non-convoluted) way in C++ to call function with different prototypes based on a name known at runtime and taking a variadic argument pack.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you.. Is there any alternative way similar to this to achieve this concept?
@Lo1234 I guess you could do something with constexpr functions that map a string to an id, and then have specialized templates for each id/ prototype, but even if that would be doable (highly unlikely) it would be too convoluted and too much hassle for something that I don't see any practical advantages. Stick to using function pointers and not function names (string).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.