Naw*_*waz 18 c++ lambda type-inference auto c++11
可能重复:
c ++ 0x中的递归lambda函数
如果我把它写成:为什么我不能递归地调用lambda:
auto a = [&]
{
static int i = 0; i++;
std::cout << i << std::endl;
if (i<10)
a(); //recursive call
};
Run Code Online (Sandbox Code Playgroud)
它给出了编译错误(ideone):
prog.cpp:8:18: error: '((const main()::<lambda()>*)this)->main()::<lambda()>::a' cannot be used as a function
prog.cpp: In function 'int main()':
prog.cpp:9:9: error: variable 'auto a' with 'auto' type used in its own initializer
Run Code Online (Sandbox Code Playgroud)
错误是什么意思?
我理解为什么我不能写这个:
auto i=i+1; //error: unable to deduce 'auto' from '<expression error>'
Run Code Online (Sandbox Code Playgroud)
我们不能写这个,因为i必须从它的初始化推断出类型,这意味着如果i自身出现在初始化(ideone)中,则无法推断出类型.但是,如果是lambda,它又如何重要?如果我没错,lambda的类型由它的参数和返回类型决定; 它不依赖于身体,如果它什么都不返回(在这种情况下,返回类型被推断为void,无论lambda体中的其他语句如何).
无论如何,我得到了一个解决方法,我可以使用std::function:
std::function<void()> a = [&]
{
static int i = 0; i++;
std::cout << i << std::endl;
if (i<10)
a();
};
Run Code Online (Sandbox Code Playgroud)
编译罚款(ideone).但我仍然有兴趣知道该auto版本无法编译的原因.
Joh*_*itb 15
原因是auto变量的lambda-expression初始化器没有特殊情况.
这种特殊情况容易出错和误用.当你提出类似a()应该工作的东西时,你需要定义规则.怎么operator()抬头?什么是类型的准确状态a?这种类型会完整吗?(这意味着你已经知道了lambda的捕获列表).一旦您以符合规范的格式制定了该规范,就可以更容易地对其进行陈述.
让你的使用情况就意味着,你需要在代码扫描进取,因为确定的类型,另一起案件a中a(),你必须确保初始化与没有任何可以"unlambda中"式结束
struct y { void operator()() { } };
template<typename T> y operator+(T, y) { return y(); }
auto x = [] { x(); } + y();
Run Code Online (Sandbox Code Playgroud)
在这种情况下,x()会调用y::operator(),而不是lambda.
就像现在一样,a简单地禁止在其整个初始化程序中提及.因为在C++中,auto是不一种类型.它只是一个代表待推导类型的类型说明符.因此,表达式永远不会有auto类型.
在我看来,auto a案例和std::function<void()> a案例之间的重要区别在于,类型std::function<void()>不知道/关心它所指的真实函数的类型是什么.写作:
std::function<void()> a;
Run Code Online (Sandbox Code Playgroud)
非常好,在这里:
auto a;
Run Code Online (Sandbox Code Playgroud)
没什么意义.所以当合成捕获时,如果你使用std::function<void()>所有需要知道的类型已经知道,而auto它还不知道.
| 归档时间: |
|
| 查看次数: |
7794 次 |
| 最近记录: |