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

时间:2017-10-09 18:13:26

标签: c++ templates c++17

给定具有以下结构的lambdas:

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的类型的情况下如何提取结果类型所证明的那样,所以我认为没有理由不应该这样做能把它拉下来。

感觉就像我拥有了每一个难题,但我似乎无法想象如何在该场景中获取重载函数的类型,以便提取{{1}的类型}。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

在你处理lambdas的特定情况下:

  • 取两个参数:第一个是非模板,第二个是模板
  • 拥有适用于所有模板参数的返回类型(例如,没有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布局。