繁体   English   中英

C++ 递归栈帧标识符

[英]C++ Recursion Stack Frame Identifier

举个例子:

int foo(){
    if(<THIS IS THE SECOND TIME YOU CALL FOO>) // I need some indicator like this
        return 1;
    else
        return foo();
}

本质上,我正在寻找一个指标来告诉我“嘿,这是你第二次调用foo ”。 (我试图避免使用 static 变量或更改foo function 本身,只是为了这个练习。)

我猜是否有任何与我可以利用和使用的函数的当前堆栈帧(或者可能是调用者堆栈帧)相关的变量?

您可以利用thread_local计数器以及RAII object 在 function 中的某个点增加一个计数器,并在线程离开 ZC1C425268E68385D1AB5074C17A94F1 时减少它。

通过在 function 的顶部附近创建具有自动存储持续时间(作为局部变量)的 object 的实例,您可以知道当前线程调用了 ZC1C425268E68385D1AB5074C17A94F4Z 多少次而尚未返回。

通过包含auto模板参数,您还可以提供 function 作为模板参数,以允许在不同的功能中重用 class。

现场示例

template<auto>
class stack_count
{
public:
    stack_count() { 
        counter()++;
    }
    ~stack_count() {
         counter()--;
    }
    
    stack_count(const stack_count&) = delete;
    void operator=(const stack_count&) = delete;

    int get() const {
        return counter();
    }

private:
    static int & counter() {
        thread_local int counter = 0;
        return counter;
    }
};

#include <iostream>

int foo()
{
    stack_count<&foo> counter;

    std::cout << counter.get() << '\n';

    if(counter.get() == 2) {
        return 42;
    }
    else {
        return foo();
    }
}

int main()
{
    const auto result = foo();
    std::cout << "foo() : " << result << '\n';
}

我假设您想检测 foo 何时被递归调用,而不是何时被调用两次。

而且我猜您正在尝试避免更改foo的 function 签名,但可以对实现做任何您想做的事情。 如果是这种情况,内部“实现”(impl)function 可以让您传递递归计数。 原始的 function foo 只是使用种子值调用实现 function:

int fooImpl(int count) {
   if (count == 2) {
       // this is the second time you've called foo

       return 0; // return any value you want
   } else {
      return fooImpl(count+1);
   }
}

int foo(){
    return fooImpl(1);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM