这就是我的简单课程的样子。
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);
}
我不能用与第一个类似的方法来做,我也尝试过这篇文章中的方法Determining return type of std::function,但无济于事。
答案 0 :(得分:2)
随意创建decltype
的参数复合体。
decltype
,导致不生成代码。编译器将完成构造所有参数的动作,在“干运行”模式下,找出返回的返回类型,然后使用它。
对于复杂的C ++代码,由于decltype
,模板和其他构造函数,编译器必须完成的所有工作确实会降低编译速度;但是decltype
最终导致没有运行时开销,无论decltype
d是什么。
答案 1 :(得分:1)
假设没有重载的函数体来打扰,我们可以实现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);
}