c++ - C++20 '熟悉的模板' lambdas:在函数指针转换中指定显式参数
问题描述
假设我在 C++20 中有以下代码,使用 P0428 中引入的显式模板参数 lambda 功能:
auto f = []<auto val>(int a) { printf("%d", val + a); };
并且我需要将 lambda 函数指针转换为f
具有void(*)(int)
显式专用值的函数指针(我需要一个显式的 C ABI 链接,成员函数调用将导致不同的参数传递寄存器),因为以下代码是非法的:
using intfn = void(*)(int);
f.template operator intfn<400>(); // illegal
f.template operator()<400>(0); // legal, but not what I need: is a member function call
(查看是否可以使用显式模板参数调用模板化用户定义转换运算符的答案?)
...是否有任何其他方法可以在当前 C++ 语言中获取函数指针,例如通过使用某种隐式转换?
解决方案
您可以利用非捕获 lambda 在 c++20 中可默认构造的事实。
#include <iostream>
#include <tuple>
template <typename F>
struct args_tuple_maker;
template <auto P, typename F, typename... Args>
auto make_function_pointer(F, std::tuple<Args...>) {
return +[](Args... args){ F{}.template operator()<P>(std::forward<Args>(args)...); };
}
int main() {
auto f = []<auto val>(int a) { printf("%d", val + a); };
auto f_ptr = make_function_pointer<200>(f, std::tuple<int>{});
static_assert(std::is_same_v<decltype(f_ptr), void(*)(int)>, "");
f_ptr(5);
}
这不是一个完美的解决方案,但也许你现在可以得到尽可能接近。可能可以改进以从 lambda 类型推断参数。
推荐阅读
- selenium - Chrome WebDriver - C#.NET 如何加载现有的 chrome cookie/配置文件,这样我就可以绕过身份验证
- python - Python Mysql 连接器。哪个更好 connection.close() 或 connection.disconnect() 或 connection.shutdown()
- google-cloud-platform - 如何使用 Cloud Function 执行服务帐户管理操作(创建、列出、删除)?
- java - 对象为空时无法进入if语句
- javascript - Next.js _app.js:模块解析失败:新项目上出现意外令牌
- laravel - 如何修复 DELETE 方法在 Laravel 中不起作用
- mongodb - Kubernetes mongo DB 用户创建
- node.js - 如何从命令行将自定义变量传递给 pm2
- playwright - 如何更改启动“npx folio”的目录
- docker - 通过 docker 镜像访问 SMB 共享还是通过 docker 主机连接到 SMB 共享?