【问题标题】:How can I detect parameter types of a function passed as a parameter?如何检测作为参数传递的函数的参数类型?
【发布时间】: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) -&gt; (any|typeerror) 类型(将haskell 和C++ 函数表示法混为一谈)。 Curry 传入函数,提供给对偶实体,完成了吗?不,不起作用,因为将auto(auto) 映射到any(any) 是不可行的,并且找到要调用的实体对偶需要对实体进行线性搜索。两者都可以修复,但基本上都是手动或自动扣签,很傻。
  • @Yakk “这意味着你的实体中只能有一个给定类型的对象,这似乎是一个奇怪的限制。”你的意思是?使用给定的代码,每个entity 可以包含任意数量的其他对象类型。

标签: c++ function templates lambda variadic-templates


【解决方案1】:

这是不可能的。例如,如果参数是包含模板(尤其是可变参数)operator() 的函子怎么办?还是一个超载的?那么“论据”是什么?

这里的核心问题是您有效地重新实现了范围,但更糟。只需在实体上提供普通迭代器,然后使用std::transform。或者查找您选择的范围库。

【讨论】:

  • “如果参数是一个包含模板化(尤其是可变参数)operator() 的函子怎么办”,我可以接受以“无法推断类型... "。
猜你喜欢
  • 1970-01-01
  • 2015-10-24
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-04
  • 1970-01-01
相关资源
最近更新 更多