【问题标题】:C++ 17: Deduce signature from Callable in a templateC++ 17:从模板中的 Callable 推断签名
【发布时间】:2020-11-27 07:48:17
【问题描述】:

如果以及如何从 C++17 中的任何可调用项中推断出签名类型? 片段:

template <typename T>
struct MyFunction;

template <typename R, typename... Args>
struct MyFunction<R(Args...)>
{
};

template <typename Callable>
auto deduceSignature(Callable&& c)
{
    // using Signature = ???;
    // return MyFunction<Signature>{ ???};}
}

我想在return 语句中使用使用类模板参数推导。 在客户端代码中我想写这个:

std::int8_t freeFunction(std::int8_t x)
{
    return x;
}

auto c1 = deduceSignature(&freeFunction);
auto c2 = deduceSignature([](std::int8_t x){
    return x;
});

【问题讨论】:

  • std::function 会自动执行此操作。最简单的可能是在未推断的上下文中使用它。类似decltype(std::function{std::declval&lt;Callable&gt;()})
  • 你能举个例子吗?如果我将此行放入 deduceSignature,那么我会得到“错误:无效使用不完整类型‘struct utils::memoize::MyFunction<:function char> >’”

标签: c++ c++17 signature callable template-argument-deduction


【解决方案1】:

std::function 可以从任何可调用对象构造,并且可以推断出签名(c++17 起)。我们可以使用它来制作提取签名的类型特征。

#include <functional>

template <typename T>
struct get_signature;

template <typename R, typename... Args>
struct get_signature<std::function<R(Args...)>> {
    using type = R(Args...);
};

template <typename Callable>
auto deduceSignature(Callable&& c)
{
    using Signature = typename get_signature<decltype(std::function{c})>::type;
}

int main() {
    deduceSignature([](int a){return 5;});
}

【讨论】:

  • 请注意,可调用对象不应重载operator() 或模板化的。 (否则无论如何签名会模棱两可)。
  • 太好了。只有一个问题:C++17 有什么特别之处?这不适用于 C++14 吗?
  • @Juergen,CTAD,我猜。
  • @Juergen CTAD 如 Evg 所述。你也可以让它在 c++11 中工作,但是你需要更多的样板。通常的方法是采用对象operator() 的签名,它适用于函子和lambda。然后你需要一个单独的特化来处理函数指针。
猜你喜欢
  • 2017-06-09
  • 1970-01-01
  • 1970-01-01
  • 2012-06-21
  • 2017-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-25
相关资源
最近更新 更多