[英]How can I use templates to deduce the parameter types of a std::function?
[英]Deduce the std::function result type and use it as a parameter
这就是我的简单课程的样子。
template <class T>
class A {
T first;
T second;
public:
A(T f, T s) : first(f), second(s) {};
template <class F>
auto foo(F f) -> decltype(f(T(), T())) {
return f(first, second);
}
};
int main() {
A<int> a = A<int>(2, 3);
a.foo([](int l, int r)->int{return l + r;});
}
我想让foo接受一个函数(或lambda或fucntion指针)f,它接受两个T类型的属性并返回f()的结果。
这段代码有效,但是我创建了虚拟参数来获取decltype的结果。 在这种情况下,它们是简单的整数,但是可以是任何整数,我当然不想从更大的类构造伪参数。 怎么处理呢?
而且,这只是一种简化的情况。 在我的情况下,foo看起来像这样:
foo(function f, result_type_of_f t1, result_type_of_f t2) {
// do something
return f(first, second, t1, t2);
}
我无法使用与第一个类似的方法来执行此操作,我还尝试了本文中的方法确定std :: function的返回类型,但无济于事。
随意创建所需的参数作为decltype
复合体。
decltype
在编译时进行评估,并且不会生成任何代码。 编译器将以“空运行”模式经历构造所有参数的动作,找出产生的返回类型并使用它。
的确,对于复杂的C ++代码,由于decltype
,模板和其他构造函数的原因,编译器必须做的所有工作确实会使编译速度变慢。 但是无论decltype
d是什么, decltype
最终都不会导致运行时开销。
假设没有麻烦的重载类函数,我们可以实现resultOf
类型特征来获取返回类型:
// std::void_t from C++17
template <class...>
struct voider {
using type = void;
};
template <class... T>
using void_t = typename voider<T...>::type;
namespace detail_resultOf {
// Base case, when it cannot be deduced
template <class F, class = void_t<>>
struct resultOf { };
// Function object: grab its operator() and try again
template <class F>
struct resultOf<F, void_t<decltype(&F::operator())>>
: resultOf<decltype(&F::operator())> { };
// Member functions
template <class Ret, class T, class... Args>
struct resultOf<Ret (T::*)(Args...)> {
using type = Ret;
};
// ...
// Free functions
template <class Ret, class... Args>
struct resultOf<Ret (*)(Args...)> {
using type = Ret;
};
// ...
}
// Public metafunction
template <class F>
using resultOf = typename detail_resultOf::resultOf<F>::type;
然后,您可以将函数编写为:
template <class F>
auto foo(F f, resultOf<F> t1, resultOf<F> t2) -> resultOf<F> {
// do something
return f(first, second, t1, t2);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.