Joh*_*itb 8 c++ lambda variadic-templates c++14
我正在玩Clang上的多态变量lambda,并注意到Clang不喜欢这个
#include <iostream>
int main() {
auto append = [](auto &&cnt, auto &&me,
auto &&a, auto &&p1, auto &&...p) -> decltype(auto)
{
if(sizeof...(p) > cnt)
return me(++cnt, me, a << p1, p..., 0);
return a;
};
append(0, append, std::cout, 1, 2, 3, 4);
}
Run Code Online (Sandbox Code Playgroud)
它打算投入"1234".一个0被附加到参数列表(并且反过来每次从前面拿走一个参数)并且计数器在我们需要停止时观察,因为我们将击中一个假人0.
但是Clang抱怨道
fatal error: recursive template instantiation exceeded maximum depth of 256
Run Code Online (Sandbox Code Playgroud)
在其反向中,大多数功能框架都是
main.cpp:6:20: note: in instantiation of function template specialization 'main()::<anonymous class>::operator()<int &, <lambda at main.cpp:4:19> &, std::basic_ostream<char> &, int &, int &, int &, int>' requested here
return me(++cnt, me, a << p1, p..., 0);
^
Run Code Online (Sandbox Code Playgroud)
这似乎是一个自我调用的递归函数模板,我无法看到无限模板实例化的疯狂.有人可以解释一下吗?标准perpahs是否禁止像lambdas那样的递归?
dyp*_*dyp 10
那应该是[dcl.spec.auto]/11(引用n3797)
如果需要具有未减少占位符类型的实体的类型来确定表达式的类型,则该程序是不正确的.
return但是,一旦在函数中看到了语句,从该语句推导出的返回类型就可以在函数的其余部分中使用,包括在其他return语句中.
因此,通过还原return语句,返回类型推导可以成功:
#include <iostream>
int main() {
auto append = [](auto &&cnt, auto &&me,
auto &&a, auto &&p1, auto &&...p) -> decltype(auto)
{
if(sizeof...(p) <= cnt)
return a;
return me(++cnt, me, a << p1, p..., 0);
};
append(0u, append, std::cout, 1, 2, 3, 4);
}
Run Code Online (Sandbox Code Playgroud)