【发布时间】:2017-06-06 10:00:19
【问题描述】:
这就是我的简单类的样子。
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 或函数指针) 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 中的方法,但无济于事。
【问题讨论】:
-
decltype不计算其操作数,因此不会构造任何额外内容。存在不可默认构造的T的问题,std::declval涵盖了该问题。但我不明白你的“非简化案例”是如何工作的。 -
另外,您的代码中绝对没有
std::function—— lambda 不是std::function。 -
好吧,也许我把它简化了一点。在我的情况下 f 需要 3 个参数,我不知道其中两个的类型,我只知道它们与返回类型相同,所以我不能真正使用 decltype,因为我不知道什么 dummy我应该在评估中创建类。
-
你需要处理重载的函数吗?如果是这样,您想在哪里解决歧义?
-
好吧,我想出了一个很好的例子——假设我们有一个二叉树,我们想要遍历它,并得到一些结果。所以 f 接受三个参数:来自节点的值、来自左子树的值和来自右子树的值。从子树返回的值可以是任何类型,但它需要与 f 的返回类型相同。不增加新的模板参数能推导出来吗?
标签: c++ c++11 templates functional-programming