重载模板化 lambda,而不知道非模板化参数的参数类型

Overload templated lambda without knowing argument type for non-templated parameters

本文关键字:参数 类型 lambda 重载 不知道      更新时间:2023-10-16

给定具有以下结构的lambda:

auto lambda_1 = [](int x, auto p) -> void {...};
auto lambda_2 = [](float x, auto p) -> int {...};

我想提取x的类型,以及返回类型,给定p的已知类型。

返回类型相当简单,只要x是默认可构造的(我可以毫无问题地提出要求):

template<typename CB_T>
void foo(CB_T cb) {
  using res_type = decltype(cb({}, std::declval<KnownP>()));
}

同样,如果没有推断出第二个参数,我可以使用类似 function_traits 的东西轻松找到第一个参数的类型。

我知道我可以按照我想要的方式触发重载解决,正如我在不知道x类型是什么的情况下如何提取结果类型所证明的那样,所以我认为没有理由不能做到这一点。

感觉我拥有拼图的每一块,但我似乎无法弄清楚如何在该场景中获取重载函数的类型以提取x的类型。

有什么建议吗?

在您处理 lambda 的特定情况下:

  • 取两个参数:第一个是非模板,第二个是模板
  • 具有对所有模板参数都有效的返回类型(例如,没有enable_if等)

然后,您可以对第一个参数使用假演绎器类型:

struct arbitrary { template <class T> operator T(); };
using res = decltype(cb(arbitrary{}, std::declval<KnownP>()));

或者,您可以使用function_traits来查找我们将要使用的特定operator()

using oper = decltype(&CB_T::template operator()<KnownP>);
using arg0 = typename function_traits<oper>::template arg<0>::type;
using res = decltype(cb(std::declval<arg0>(), std::declval<KnownP>());
<小时 />

不过,两者都非常特定于这种特定的 lambda 布局。