Dr.Death
Dr.Death

Reputation: 93

Wrap std::function in class with function name as string

I'm trying to wrap std::function in a class with adds a readable string of the function name to std::function.

I did come up with this simple class (defined in header.hpp)

template <typename... Args>
class CExtended_Function
{
public:
    explicit CExtended_Function(
        const std::function<void(Args...)>& func_type, const std::string& func_name)
        : func(func_type)
        , function_name(func_name)
    {
    }

    /// Function
    const std::function<void(Args...)> func;

    /// Function Name
    const std::string function_name;
};

My own make function looks like this. The Idea is to pass the Function Name to the make function as a template argument. And the make function should create a std::function instance and a std::string instance.

(defined in header.hpp)

template <typename Func_T, typename... Args>
CExtended_Function<Args...> Make_Extended_Function()
{
    std::function<void(Args...)> func(Func_T);
    std::string func_name(NCommonFunctions::type_name<Func_T>());
    CExtended_Function<Args...> res(func, func_name);

    return res;
}

where type_name<My_Function>() returns the name of the function as std::string_view

defined in header.hpp

template <class T>
constexpr std::string_view type_name();

However when using my make function like this

used in source.cpp

static void Test_Callback();

auto test = Make_Extended_Function<Test_Callback>();

I'm getting the error :

Symbol 'Make_Extended_Function' could not be resolved

Could you give me a hint why I'm getting this error?

Upvotes: 0

Views: 333

Answers (2)

Jarod42
Jarod42

Reputation: 218088

Make_Extended_Function expects types. you provide function pointer, so an error.

The easier fix would probably be to change Make_Extended_Function to:

template <typename... Args>
CExtended_Function<Args...>
Make_Extended_Function(const std::function<void(Args...)>& f, const std::string& name)
{
    return CExtended_Function<Args...>(f, name);
}

(but you have to call it with a std::function to allow deduction).

NCommonFunctions::type_name seems to have identical issues than Make_Extended_Function.

A probably better fix would be to drop std::function and take functor directly:

template <typename F>
class CExtended_Function
{
public:
    explicit CExtended_Function(
        const F& f, const std::string& name)
        : f(f)
        , name(name)
    {
    }

    F f;
    std::string name;
};

Upvotes: 0

SPD
SPD

Reputation: 388

a couple of things you may need to change in your code:

  1. Test_Callback is a function, you can only pass function pointer as a non-type template argument. I.e. it should be auto test = Make_Extended_Function<&Test_Callback>(); instead;
  2. If you're passing a function pointer as template argument, the syntax is template<function+pointer_type function pointer>(similar to template), so make_extended_function should be template <auto Func_T, typename... Args> CExtended_Function<Args...> Make_Extended_Function() instead (I use "auto" here to make things easier). And the same for type_name()

Sample code:

#include <iostream>
#include <functional>
#include <string_view>

using namespace std;
namespace NCommonFunctions {
template <auto T>
std::string type_name() { return "a_name"; }
}
template <typename... Args>
class CExtended_Function
{
public:
    explicit CExtended_Function(
        const std::function<void(Args...)>& func_type, const std::string& func_name)
        : func(func_type)
        , function_name(func_name)
    {
    }

    /// Function
    const std::function<void(Args...)> func;

    /// Function Name
    const std::string function_name;
};

template <auto Func_T, typename... Args>
CExtended_Function<Args...> Make_Extended_Function()
{
    std::function<void(Args...)> func(Func_T);
    std::string func_name(NCommonFunctions::type_name<Func_T>());
    CExtended_Function<Args...> res(func, func_name);

    return res;
}
 void Test_Callback() { cout << "test" << endl; }
int main () {
    auto test = Make_Extended_Function<&Test_Callback>();
    test.func();
}

Upvotes: 1

Related Questions