函数指针是否有声明?
Is There a declval for Function Pointers?
我有一个函数,我需要测试是否可以将给定类型的参数传递给它。例如:
template<typename T, auto F>
decltype(F(declval<T>{})) foo();
调用 foo<int, bar>()
会做两件事:
- 将
foo
的 return 类型设置为与 bar
相同的 return 类型
- 确保
bar
是一个接受参数的函数
输入 T
不幸的是我无法访问 auto
模板类型,但我仍然想完成这两个。我需要的是函数指针的 decltype
,它允许我做这样的事情:
template <typename T, typename F>
decltype(declval<F>(declval<T>{})) foo();
所以我仍然可以调用 foo<int, bar>()
并得到相同的结果。当然,函数指针没有 declval
。但是我还有其他方法可以做到这一点吗?
Of course there isn't a declval for function pointers.
你是什么意思? 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_t
和 std::is_invocable
代替。我建议模仿那些以获得最无缝的升级。
我有一个函数,我需要测试是否可以将给定类型的参数传递给它。例如:
template<typename T, auto F>
decltype(F(declval<T>{})) foo();
调用 foo<int, bar>()
会做两件事:
- 将
foo
的 return 类型设置为与bar
相同的 return 类型
- 确保
bar
是一个接受参数的函数 输入T
不幸的是我无法访问 auto
模板类型,但我仍然想完成这两个。我需要的是函数指针的 decltype
,它允许我做这样的事情:
template <typename T, typename F>
decltype(declval<F>(declval<T>{})) foo();
所以我仍然可以调用 foo<int, bar>()
并得到相同的结果。当然,函数指针没有 declval
。但是我还有其他方法可以做到这一点吗?
Of course there isn't a declval for function pointers.
你是什么意思? 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_t
和 std::is_invocable
代替。我建议模仿那些以获得最无缝的升级。