我有一个功能,我需要测试我是否可以传递给定类型,它的参数。 例如:
template<typename T, auto F>
decltype(F(declval<T>{})) foo();
主叫foo<int, bar>()
做两两件事:
- 台返回类型
foo
将具有相同的返回类型bar
- 确保
bar
是接受类型的参数的函数T
不幸的是,我没有进入auto
模板类型,但我还是要完成这两个。 我需要的是一个decltype
函数指针,这样可以让我做这样的事情:
template <typename T, typename F>
decltype(declval<F>(declval<T>{})) foo();
所以我仍然可以称之为foo<int, bar>()
并得到同样的结果。 当然,没有一个declval
函数指针。 但有另一种方式,我可以做到这一点?
当然没有函数指针一declval。
你什么意思? std::declval
与函数指针类型的工作完美:
template<typename F, typename... Args>
using call_t = decltype(std::declval<F>()(std::declval<Args>()...));
在这个例子中, F
可以是一个函数指针型,λ型或任何类型的可调用。
下面是使用的例子:
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")
需要注意的是这一切都可以被替换std::invoke_result_t
和std::is_invocable
在C ++ 17。 我建议那些模仿有最无缝的升级。