Search code examples
c++functiontemplatescalloverloading

C++ template overload call


I am trying to implement an execution pattern which takes any function and executes it with its own conditions/preparations. Regardless of this being a useful thing to do, it just doesn't work. It seems i can't access the template overload of the "Execute"-function (called in "main").

Specifically: Why can't i call the overloaded template function of Execute?

This is the full program:

#include "stdafx.h"
#include <functional>

class TransparentFunctionWrapper
{
public:
    virtual void Execute(std::function<void()> executeFunction) = 0;

    template<class C>
    C Execute(std::function<C(void)> executeFunction) // template-overload of the abstract function which will implicitly call it
    {
        C ret;
        Execute( // calls the abstract function with a lambda function as parameter
        [ret, executeFunction](void) -> C       // lambda declaraction
        {                                       //
            ret = executeFunction;              // lambda body
        });                                     // 
        return ret;
    }
};

class ExampleExecutor : public TransparentFunctionWrapper
{
public:
    virtual void Execute(std::function<void()> executeFunction)
    {
        printf("executed before.");
        executeFunction();
        printf("executed after.");
    }
};

void DoStuff() {}
int ReturnStuff() { return -5; }

int main()
{
    ExampleExecutor executor;

    executor.Execute(DoStuff);
    int i = executor.Execute<int>(ReturnStuff);     // Why does this not work? ERROR: "type name is not allowed"

    getchar();
    return 0;
}

Note: Visual Studio marks

Execute<int>(ReturnStuff) // "int" is marked as Error: type name is not allowed

The compilation puts out the error

"type 'int' unexpected"

Thanks to everyone willing to help!


Solution

  • ExampleExecutor::Execute is not overriding TransparentFunctionWrapper::Execute, and it is hiding it in the executor.Execute<int> call.

    You must explicitly call TransparentFunctionWrapper::Execute, as it is hidden by ExampleExecutor::Execute. Here's a possible way of doing that:

    int i = executor.TransparentFunctionWrapper::Execute<int>(ReturnStuff); 
    

    live example on coliru