1

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

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>()并得到相同的结果。当然没有declvalfor 函数指针。但是还有另一种方法可以做到这一点吗?

4

1 回答 1

3

当然,函数指针没有 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++17std::invoke_result_t中替换。std::is_invocable我建议模仿那些进行最无缝的升级。

于 2019-03-01T15:23:20.157 回答