0

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?

5
  • Are you one of the many that tried to implement a template in a .cpp file? Commented Jul 21, 2019 at 12:16
  • nope all templates are defined and implemented in a header file. Commented Jul 21, 2019 at 12:27
  • Does the problem go away if you put everything in a single file? Commented Jul 21, 2019 at 13:31
  • I wrote this as an answer, but then I realized that this might not be the problem and deleted it. Regardless, you are passing the function as a type parameter, but it is not a type, please take a look at godbolt.org/z/NnESxJ . It this what you wanted to achieve? If you apply my fix, does it compile? Commented Jul 21, 2019 at 14:48
  • @L.F. nope it was not an include problem. Commented Jul 21, 2019 at 21:01

2 Answers 2

1

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();
}
Sign up to request clarification or add additional context in comments.

Comments

0

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;
};

Comments

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.