【发布时间】:2015-04-25 11:42:19
【问题描述】:
问题
我必须编写一个函数用作:
obj.transform([](x& a, y& b) { ... });
obj.transform([](x& a) { ... });
obj.transform([](y const& a, x& b, z const& c) { ... });
obj.transform([a, b](z const& c) { ... });
...
在函数声明中,我需要弄清楚传入的参数的类型。
那么函数体就是这样的形式(假设x是一个成员对象,argfn是传入的函数):
if (x.mfn1<std::remove_reference_t<Args>...>())
argfn(x.mfn2<std::remove_reference_t<Args>>()...);
上下文
如果您问自己,为什么并且您不知道这有什么用,或者如果您认为这是一个 XY 问题,那么您可以找到 the context right here。
我的尝试
尝试 #1
template<typename... Args>
void fn(std::function<void(Args...)>) { ... }
这是doesn't work,因为显然无法在 std::function 和任何 lambda 之间进行转换。
尝试 #2
template<typename... Args>
void fn(void(*)(Args...)) { ... }
这适用于上面的第一个、第二个和第三个示例(在每个 lambda 前面添加 + 以强制转换为指向函数的指针),但 fails on the fourth。
【问题讨论】:
-
因此,您传入可调用对象,推断调用它所需的类型,检查您是否具有这些类型,然后调用。这意味着您的实体中只能有一个给定类型的对象,这似乎是一个奇怪的限制。对 your linked code 的两个小改动使其可以编译。
-
您需要参数类型?如果 lambda 不是通用的,只需查看它的
operator()。 -
说疯了,实体的对偶是
any(any) -> (any|typeerror)类型(将haskell 和C++ 函数表示法混为一谈)。 Curry 传入函数,提供给对偶实体,完成了吗?不,不起作用,因为将auto(auto)映射到any(any)是不可行的,并且找到要调用的实体对偶需要对实体进行线性搜索。两者都可以修复,但基本上都是手动或自动扣签,很傻。 -
@Yakk “这意味着你的实体中只能有一个给定类型的对象,这似乎是一个奇怪的限制。”你的意思是?使用给定的代码,每个
entity可以包含任意数量的其他对象类型。
标签: c++ function templates lambda variadic-templates