C++ lambda&x27的规格;s的返回值不为';行不通

C++ lambda&x27的规格;s的返回值不为';行不通,c++,recursion,lambda,return-value,auto,C++,Recursion,Lambda,Return Value,Auto,我有个问题。 函数“\uu sub”解析一个字符串,如“1x+(5y-2)”。每次看到“(”,它都会调用自己来精确解析括号中的内容。 下面是一些伪代码,说明了问题: auto __sub = [&needed_fn](const char *& iter, char end_at) -> int { for (; *iter != end_at; iter++) { if () { int number = needed_fn(iter);

我有个问题。 函数“
\uu sub
”解析一个字符串,如
“1x+(5y-2)”
。每次看到“
”,它都会调用自己来精确解析括号中的内容。 下面是一些伪代码,说明了问题:

auto __sub = [&needed_fn](const char *& iter, char end_at) -> int {
  for (; *iter != end_at; iter++) {
    if () {
      int number = needed_fn(iter);
    } else if (*iter == '(') {
      int sub_result = __sub(iter, ')');
    }
  }
  return 0; // temporarily, as for debugging purposes only needed
};
但这不起作用。起初没有(
->int
)的规范。 无论是否指定返回值,它都不适用于这两种情况

它说:

a.cpp: In lambda function:
a.cpp:97:22: error: use of ‘__sub’ before deduction of ‘auto’
 int sub_result = __sub(it, ')');

建议:将
\uuu sub
定义为
std::function

std::function\uuuu sub;
__sub=[&needed\u fn](常量字符*&iter,字符结束)->int{
对于(;*iter!=end_at;iter++){
如果(/*???*/){
国际热核试验堆(iter)所需的整数;
}如果(*iter=='('),则为else{
int sub_结果=uu sub(国际热核实验堆,');
}
返回0;
};

否则,编译器无法在
\uu sub()的主体内使用相同的
\uu sub()
来推断(
auto
)的类型

我不同意这是一个鸡和蛋的问题,或者至少是一个可解决的问题,而是建议这是语言的一个怪癖,因为你可以用手完成几乎相同的事情

为了稍微简化讨论,以一个常见的递归示例factorial()为例:

它会失败,出现如下错误:

<source>: In lambda function:
<source>:7:24: error: use of 'factorial' before deduction of 'auto'
    7 |             return n * factorial(n-1);
      |                        ^~~~~~~~~
我们的代码现在更正确了。编译器怎么说

<source>:3:24: error: use of 'factorial' before deduction of 'auto'
    3 |     auto factorial = [&factorial](int n) {
      |                        ^~~~~~~~~
<source>: In lambda function:
<source>:7:24: error: use of 'factorial' before deduction of 'auto'
    7 |             return n * factorial(n - 1);
      |                        ^~~~~~~~~

这是可行的,在一个完美的世界里,lambda形式也会出现。在 Auto <代码> >代码> >阶乘中,它非常像不完整的类型。C++中允许不完整类型的引用和指针,包括那些包含它们的类或结构。s或指针。因此,这在语言的精神范围内都是可能的。不同的语言可以将

阶乘的类型推断为lambda的类型,而lambda类型是不完整的,即在尝试创建lambda类型的定义之前

在C++中,你有一些可能的解决方案。首先,你可以用手工编写闭包类型(如in)。< /P> 其次,您可以删除该类型,如另一个答案()中所示:

这通过使调用运算符成为模板来延迟对类型的需要,但代价是使用不当,例如,
factorial(4,factorial)


希望这能有所帮助!

那么“if()”呢?“if”在那里不起作用。
std::function\uuuu sub;\uuuu sub=[&needed\ufn,&uuuu sub]…
起作用了,但为什么即使我明确指定了返回值,它也不能按我的方式起作用?@u1070;
;一种鸡和蛋的问题:每个lambda都有它的特定类型;但是如果定义
auto
一个lambda并在它的主体中使用它,则会强制编译器使用
\uu sub()
的类型来决定
\uu sub()的类型
。如果说
\uu sub
是一个
std::function
,就可以避免这个问题。使用lambda表达式有实际价值吗?这看起来像是编写一个正则函数(以required\fn为参数)另外,除非您的实际代码明显不同,否则如果找不到预期的字符,您将在缓冲区结束后进行迭代。
<source>: In lambda function:
<source>:7:24: error: use of 'factorial' before deduction of 'auto'
    7 |             return n * factorial(n-1);
      |                        ^~~~~~~~~
auto factorial = [&factorial](int n) {
    if (n == 0)
        return 1;
    else
        return n * factorial(n - 1);
};
<source>:3:24: error: use of 'factorial' before deduction of 'auto'
    3 |     auto factorial = [&factorial](int n) {
      |                        ^~~~~~~~~
<source>: In lambda function:
<source>:7:24: error: use of 'factorial' before deduction of 'auto'
    7 |             return n * factorial(n - 1);
      |                        ^~~~~~~~~
struct factorial_t
{
    factorial_t& factorial;
    auto operator()(int n) const
    {
        if (n == 0)
            return 1;
        else
            return n * factorial(n - 1);
    }
};

int main()
{
    factorial_t factorial{factorial};
}
std::function<int(int)> factorial = [&factorial](int n) {
    if (n == 0)
        return 1;
    else
        return n * factorial(n - 1);
};
auto factorial = [](int n, auto&& factorial) {
    if (n == 0)
        return 1;
    else
        return n * factorial(n - 1, factorial);
};
auto factorial_impl = [](int n, auto&& factorial_impl) {
    if (n == 0)
        return 1;
    else
        return n * factorial_impl(n - 1, factorial_impl);
};

auto factorial = [&factorial_impl](int n) {
    return factorial_impl(n, factorial_impl);
};