C++20 - 在模板中调用声明为 auto 的函数

C++20 - Call function declared as auto in template

我正在用 C++ 构建一个 nodejs 插件,我正在尝试制作一个从 C++ 到节点的函数导出器。更确切地说,我正在尝试构建与此类似的功能:

std::string func(std::string param)
{
  return param;
}

void func_wrapper(const v8::FunctionCallbackInfo<v8::Value>& args)
{
    Isolate* isolate = args.GetIsolate();

    std::string str(*v8::String::Utf8Value(isolate, args[0]));
    auto ret = func(str).c_str();

    args.GetReturnValue().Set(String::NewFromUtf8(
        isolate, ret, NewStringType::kNormal).ToLocalChecked()); 
}

void Initialize(v8::Local<v8::Object> exports) 
{
  NODE_SET_METHOD(exports, "func", func_wrapper);
}

NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)

我正在尝试更轻松地导出更多函数,而无需手动创建包装器,如下所示:

template<auto Func>
void Export(const v8::Local<v8::Object>& exports, std::string name)
{
    auto wrapper = [](const v8::FunctionCallbackInfo<v8::Value>& args) {
        Isolate* isolate = args.GetIsolate();
        unsigned int lg = args.Length();

        auto ret = Func(args[0], args[1], ...) //how to?
    };
    NODE_SET_METHOD(exports, name.c_str(), wrapper);
}

std::string func(std::string param)
{
  return param;
}

void Initialize(v8::Local<v8::Object> exports) 
{
  Export<func>(exports, "func");
}

NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)

但我不知道如何在我的导出函数中调用 Func。有什么方法可以给一个函数一个一个的参数吗?

包括:

#include <functional>
#include <utility>
#include <type_traits>
#include <concepts>
#include <string>

转换函数:

decltype(auto) Convert(v8::Isolate* isolate, const v8::Local<v8::Value>& value,
                       std::type_identity<std::string>)
{
    return *v8::String::Utf8Value(isolate, value);
}

template <std::integral T>
decltype(auto) Convert(v8::Isolate* isolate, const v8::Local<v8::Value>& value,
                       std::type_identity<T>)
{
    return v8::Integer::Cast(*value)->Value();
}

呼叫代表:

template <typename R, typename... Args>
auto Call(v8::Isolate* isolate, std::function<R(Args...)> f,
          const v8::FunctionCallbackInfo<v8::Value>& args)
{
    static_assert(sizeof...(Args) <= v8::FunctionCallbackInfo<v8::Value>::kArgsLength);
    return [&] <std::size_t... Is> (std::index_sequence<Is...>) {
        return f(Convert(isolate, args[Is],
                         std::type_identity<std::remove_cvref_t<Args>>{})...);
    }(std::index_sequence_for<Args...>{});
}

导出函数:

template <auto Func>
void Export(const v8::Local<v8::Object>& exports, const std::string& name)
{
    auto wrapper = [](const v8::FunctionCallbackInfo<v8::Value>& args) {
        v8::Isolate* isolate = args.GetIsolate();
        unsigned int lg = args.Length();
        auto ret = Call(isolate, std::function{ Func }, args);
    };
    NODE_SET_METHOD(exports, name.c_str(), wrapper);
}