samedi 22 août 2015

C++ - Determine instance of foo in templated function pointer argument call

I'm playing around with function-pointer calls and callbacks and trying to write a function which can take any function-pointer, log the function call and call the function-pointer after. Here is a code to show you what I'm trying to do:

#include<iostream>
#include<string>
#include<functional>


int foo1(int k)
{
    return k * 2;
}

auto foo2(double k, int z, float y) -> decltype((k + z + y) + 10)
{
    return (k + z + y) + 10;
}

std::string foo3(std::string&& _str)
{
    return _str.append(" yo");
}

int foo4(std::function<int(int)> Fn, int&& val)
{
    return Fn(std::forward<int>(val));
}

template<typename Fn>
int foo5(Fn fn)
{
    return 10;
}

template <typename T, typename... args>
T(*LogAndCall(T(*ptr)(args...)))(args...)
{
    std::cout << "Logging function call to: " << ptr << " with " << sizeof...(args) << " argument(s)" << std::endl;
    return ptr;
}

int main()
{
    //call foo1
    auto r1 = LogAndCall(foo1)(20);
    std::cout << "Ret value: " << r1 << std::endl << std::endl;

    //call foo2
    auto r2 = LogAndCall(foo2)(12.63, 233, 12.35f);
    std::cout << "Ret value: " << r2 << std::endl << std::endl;

    //call foo3
    auto r3 = LogAndCall(foo3)("hihi");
    std::cout << "Ret value: " << r3 << std::endl << std::endl;

    //call foo4
    auto r4 = LogAndCall(foo4)([](int&& x){
        return x*10;
    },100);
    std::cout << "Ret value: " << r4 << std::endl << std::endl;

    //call foo5
    auto r5 = LogAndCall(foo5)([](int x){ //cannot determine which instance of function template "foo5" is intended
        return x;
    });

    std::cin.get();
    return 0;
}

As you can see, everything works except when i try to call foo5 with the following error:

BlockquoteSeverity Code Description Project File Line Error C2783 'T (__cdecl *LogAndCall(T (__cdecl *)(args...)))(args...)': could not deduce template argument for 'T' Tutorial2 c:\users\nilo\documents\visual studio 2015\projects\tutorial2\tutorial2\main.cpp 60

Severity Code Description Project File Line Error (active) cannot determine which instance of function template "foo5" is intended Tutorial2 c:\Users\nilo\Documents\Visual Studio 2015\Projects\Tutorial2\Tutorial2\Main.cpp 60

Severity Code Description Project File Line Error (active) no instance of function template "LogAndCall" matches the argument list Tutorial2 c:\Users\nilo\Documents\Visual Studio 2015\Projects\Tutorial2\Tutorial2\Main.cpp 60

As you can see, i want to use templated Fn as a lambda function which works for std::function but not without it. What am i missing?

Do I need to specify foo5

Aucun commentaire:

Enregistrer un commentaire