使用Hindley-Milner类型推断的某种变体的编程语言可以很容易地推断出表达式的类型,例如
let rec fix f x = f (fix f) x 而C++1y中的返回类型推断由于以下原因而失败:
int main() {
auto fix =
[&](auto f) {
return [&](auto x) {
return f(fix(f))(x);
};
};
return 0;
}我用clang 3.5和命令尝试了一下
clang++ -std=c++1y fix.cc我得到了
fix.cc:7:18: error: variable 'fix' declared with 'auto' type cannot appear in its
own initializer
return f(fix(f))(x);C++的返回类型推断中缺少什么,当必须推断返回类型时,不允许在自己的初始化器中使用变量?我可以做些什么来解决这个问题,更好的是,我们可以在语言中做些什么来解决这个问题?
发布于 2014-02-08 03:11:28
这里的问题不是类型推断的问题。直接的问题是,不存在用于lambda引用自身的语法,即使这样做是完全合理和可实现的。可以很容易地定义引用自身的函数对象。
您的特定lambda有一个问题,因为您正在通过引用捕获本地对象,然后允许该引用脱离其有效范围,但如果我们将其更改为:
int main() {
auto fix =
[](auto &f) {
return [&](auto x) {
return f(fix(f))(x);
};
};
return 0;
}然后我们可以编写和使用等价的函数对象:
#include <iostream>
struct lambda1 {
template<typename F>
auto operator() (F &f) const;
};
template<typename F>
struct lambda2 {
lambda1 const &l1;
F &f;
lambda2(lambda1 const &l1, F &f) : l1(l1), f(f) {}
template<typename X>
auto operator() (X x) const { return f( l1(f))(x); }
};
template<typename F>
auto lambda1::operator() (F &f) const {
return lambda2<F>(*this, f);
} // ^
// |
// --- there's no syntax to do this inside a lambda.
int main() {
lambda1 fix;
auto f = [](auto&&){ return [](int x) {return x;}; };
std::cout << fix(f)(5) << '\n';
}如果添加某种语法以允许lambda引用其自身,那么这将是很好的。
https://stackoverflow.com/questions/21634889
复制相似问题