将 std::function 包装在类中,函数名称为字符串

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

本文关键字:函数 字符串 function std 包装      更新时间:2023-10-16

我正在尝试将std::function包装在一个类中,并将函数名称的可读string添加到std::function中。

我确实想出了这个简单的课程(在标题.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;
};

我自己的 make 函数看起来像这样。想法是将函数名称作为模板参数传递给 make 函数。make 函数应该创建一个std::function实例和一个std::string实例。

(在标题.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;
}

其中type_name<My_Function>()返回函数的名称为 std::string_view

在 header.hpp 中定义

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

但是当像这样使用我的 make 函数时

在源中使用.cpp

static void Test_Callback();
auto test = Make_Extended_Function<Test_Callback>();

我收到错误:

无法解析符号"Make_Extended_Function">

你能给我一个提示为什么我会收到这个错误吗?

您可能需要

在代码中更改一些内容:

    Test_Callback函数,
  1. 则只能将函数指针作为非类型模板参数传递。 即它应该被auto test = Make_Extended_Function<&Test_Callback>();;
  2. 如果要将函数指针作为模板参数传递,则语法template<function+pointer_type function pointer>(类似于模板(,因此应该make_extended_function改为template <auto Func_T, typename... Args> CExtended_Function<Args...> Make_Extended_Function()(我在这里使用"auto"以使事情变得更容易(。type_name(( 也是如此

示例代码:

#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();
}

Make_Extended_Function需要类型。 您提供函数指针,因此出现错误。

更简单的解决方法可能是将Make_Extended_Function更改为:

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

(但你必须用std::function来调用它才能允许扣除(。

NCommonFunctions::type_name似乎有与Make_Extended_Function相同的问题。

一个可能更好的解决方法是删除 std::function 并直接获取函子:

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