功能指针是否有declval?

时间:2019-03-01 15:11:44

标签: c++ function-pointers sfinae return-type declval

我有一个函数,我需要测试是否可以将给定类型的参数传递给它。例如:

template<typename T, auto F>
decltype(F(declval<T>{})) foo();

呼叫foo<int, bar>()有两件事:

  1. 设置foo的返回类型与bar的返回类型相同
  2. 确保bar是一个接受参数的函数 输入T

不幸的是,我没有访问auto模板类型的权限,但是我仍然想同时实现这两种类型。我需要的是decltype用于函数指针,这将使我能够执行以下操作:

template <typename T, typename F>
decltype(declval<F>(declval<T>{})) foo();

所以我仍然可以调用foo<int, bar>()并获得相同的结果。当然,函数指针没有declval。但是我还有另一种方法可以做到这一点吗?

1 个答案:

答案 0 :(得分:2)

  

当然,函数指针没有declval。

什么意思? std::declval与函数指针类型完美配合:

template<typename F, typename... Args>
using call_t = decltype(std::declval<F>()(std::declval<Args>()...));

在此示例中,F可以是函数指针类型,lambda类型或任何可调用类型。

这是用法示例:

template<typename T, typename F>
auto foo() -> call_t<F, T>;

另一个使用检测习惯用法的示例(可在C ++ 11中实现):

template<typename F, typename... Args>
using is_callable = is_detected<call_t, F, Args...>;

static_assert(is_callable<void(*)(int), int>::value, "callable")

请注意,所有这些都可以在C ++ 17中用std::invoke_result_tstd::is_invocable代替。我建议模仿那些具有最无缝的升级。