【问题标题】:Infinite recursion in copy constructor复制构造函数中的无限递归
【发布时间】:2014-03-03 23:16:42
【问题描述】:

我在程序的一部分中遇到了问题,我将一个充当 lambda 函数的对象传递给另一个函数(我需要捕获一个 const this 指针,因此我不能使用实际的 lambda)。这导致我的 lambda 的复制构造函数被调用,它再次调用复制构造函数,最终堆栈溢出。我明白发生了什么,但我不确定为什么复制构造函数会调用自己或如何解决这个问题。我已经重现了下面的问题。

编译器:MSVC 2010

#include <functional>

void synchronizedExecution(std::function<void()> function) {
    function();
}

int main(int argc, char *argv[])
{

    int b = 0;

    class Function : public std::function<void()> {
    public:
        int& b;
        Function(int& b) :
            b(b) {}
        void operator()() {}
    } function(b);

    synchronizedExecution(function);

    return 0;
}

【问题讨论】:

  • main() 中的类声明/定义看起来错误(至少声明后缺少分号!)。
  • 声明对我来说看起来很好。分号就在实例之后。
  • g++下没问题(无递归)...你用的是Visual Studio 2010还是2012?
  • 类声明/定义很好 - 它只是使用另一种语法来声明类的变量并使用构造函数对其进行初始化,传递b。
  • 继承std::function 是一个可怕的想法。你为什么这样做?

标签: c++ copy-constructor default-constructor


【解决方案1】:

我可以帮助您解决“如何解决此问题”部分 - 将您的功能更改为

void synchronizedExecution(const std::function<void()>& function)

【讨论】:

  • 视情况而定,我可以看到用户希望将函数实际复制到哪里(因为 synchronizedExecution 是一个函数,我猜 async 也是一个选项)
  • @MadScienceDreams:按值传递将是 slicing。坏消息。
  • @FredLarson 我在想,但它不会在 g++ 中展开,我仍在试图找出原因......
  • @MadScienceDreams:我敢打赌它也不叫Function::operator()()。
  • 我的代码正在以某种方式增长,这让我认为即使我通过引用传递,我也必须在某个时候复制该函数。但现在我认为情况并非如此,所以我认为这会奏效。
【解决方案2】:

首先,要解决您的问题,您可能可以通过引用而不是值来传递对象。

其次,您的编码很容易出错。当您引入一个新名称并且它与现有名称相同时,您会遇到编译器解决的冲突,但您并不总是得到预期的结果。例如

   class Function
        int& b;
        Function(int& b) :
            b(b) {}

我真的不确定,哪个b 将被替换为 ()、类成员或函数参数。 AFAIR,班级成员有优先权,这不是你想要的。我怀疑你的实际问题有同样的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 2018-06-24
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多