我了解lambda函数如何工作。问题是程序在编译器推断出“ auto”应该是什么之前调用了函数recursiveFunction()。事实是,它是一个递归函数,因此该函数本身在定义中。
#include <iostream>
using namespace std;
template <class T>
class Class {
public:
int foo(int x);
};
template <class T>
int Class<T>::foo(int x) {
auto recursiveFunction = [=](int n)->int {
if (n <= 1) return 1;
else return n*recursiveFunction(n-1);
};
return recursiveFunction(x);
}
int main() {
Class<int> c;
cout << c.foo(5) << endl;
return 0;
}
我还使用类使用模板来实现此目的,以防造成问题。
这是错误消息:
main.cpp: In instantiation of 'int Class<T>::foo(int) [with T = int]':
main.cpp:21:20: required from here
main.cpp:14:40: error: use of 'recursiveFunction' before deduction of 'auto'
else return n*recursiveFunction(n-1);
谢谢!
答案 0 :(得分:4)
已回答here:
第二个片段进入[dcl.spec.auto] / 10:
如果需要使用具有未推导的占位符类型的实体的类型来确定表达式的类型,则程序格式错误。
需要foo类型来确定lambda主体中表达式foo的类型,但是到那时您还没有推导出foo的类型,因此程序格式错误。
更多参考文献:
修正:https://godbolt.org/z/np3ULe
#include <iostream>
#include <functional>
template <class T>
class Class {
public:
int foo(int x);
};
template <class T>
int Class<T>::foo(int x) {
std::function<int(int)> fac = [&fac](int n) -> int {
if (n <= 1)
return 1;
else
return n * fac(n - 1);
};
return fac(x);
}
int main() {
Class<int> c;
std::cout << c.foo(5) << std::endl;
return 0;
}
答案 1 :(得分:0)
结合可能的答案:
因此,您可以不用麻烦的auto
和相关的推论,并保证提前知道类型。
template <class T>
int Class<T>::foo(int x) {
std::function<int(int)> recursiveFunction;
recursiveFunction = [=](int n)->int {
if (n <= 1) return 1;
else return n*recursiveFunction(n-1);
};
return recursiveFunction(x);
}
namespace {
int recursiveFunction(int) {
if (n <= 1) return 1;
else return n*recursiveFunction(n-1);
}
}
int Class<T>::foo(int x) {
return recursiveFunction(x);
}
#include <iostream>
#include <functional>
template <class T>
class Class {
public:
int foo(int x);
};
template<class F>
struct function_traits;
template<class R, class T>
struct function_traits<R(T)> {
typedef R return_type;
typedef T arg_type;
};
// function pointer
template<class R, class... Args>
struct function_traits<R(*)(Args...)> : public function_traits<R(Args...)>{}};
template <typename Signature>
auto y (std::function<typename function_traits<Signature>::return_type(typename function_traits<Signature>::arg_type, std::function<Signature>)> f)
-> std::function<Signature>
{
return [f](typename function_traits<Signature>::arg_type n) -> typename function_traits<Signature>::return_type { return f(n,y(f)); };
}
template <class T>
int Class<T>::foo(int x) {
return y<int(int)>([=](int n, auto recursiveFunction) -> int {
if (n <= 1) return 1;
else return n*recursiveFunction(n-1);
})(5);
}
int main() {
Class<int> c;
std::cout << c.foo(5) << std::endl;
return 0;
}
答案 2 :(得分:0)
如果您想避免使用std::function
,则可以这样做(通用Lambda需要C ++ 14):
int Class<T>::foo(int x) {
auto recursiveFunction = [](auto recFunc, int n) -> int
{
if (n <= 1) return 1;
else return n * recFunc(recFunc, n - 1);
};
return recursiveFunction(recursiveFunction, x);
}