【问题标题】:The target set to std::function is lost设置为 std::function 的目标丢失
【发布时间】:2017-01-25 18:09:36
【问题描述】:

我为 std::function 设置的目标丢失了,我不知道为什么我可能忽略了这个程序中的一些小错误。有人可以帮忙吗?

class Test 将 lambda 注册到单例类,但是当尝试调用回调时,std::function 中设置的目标丢失。

#include <iostream>
#include <functional>

using namespace std;

class callback_store final
{

    using callback_func_type = std::function<void()>;

    public:
    static callback_store instance()
    {
        static callback_store instance;
        return instance;
    }

    void register_callback(callback_func_type func)
    {
        std::cout << "register_callback() <<<" << std::endl;
        m_func = func;

        // I am able to call the targets from here.
        std::cout << "register_callback() func() " <<  std::endl;
        func();
        std::cout << "register_callback() m_func() "  << std::endl;
        m_func();

        // some stats
        std::cout << "register_callback() :: " << func.target_type().name() << std::endl;
    }

    void invoke_callback()
    {
        std::cout << "invoke_callback() <<< " << std::endl;

        if (!m_func)
        {
            // This block is hit! Why
            std::cout << "invoke_callback() :: m_func empty" << std::endl;
            return;
        }

        return m_func();
    }

    private:
    callback_func_type m_func;

};


class Test final
{
  public:
  Test()
  {
      callback_store::instance().register_callback([this](){do_test();});
  }

  ~Test()
  {
      std::cout << "destructor" << std::endl;
  }

  private:
  void do_test()
  {
      std::cout << "do_test() invoked !!" << std::endl;
  }

};

int main()
{
   cout << "Hello World" << endl; 

   Test t;

   callback_store::instance().invoke_callback();


   return 0;
}

输出:

sh-4.3$ g++ -std=c++11 -o main *.cpp
sh-4.3$ main
Hello World
register_callback() <<<
register_callback() func()
do_test() invoked !!
register_callback() m_func()
do_test() invoked !!
register_callback() :: ZN4TestC4EvEUlvE_
invoke_callback() <<<
invoke_callback() :: m_func empty
destructor

【问题讨论】:

  • 您的单例实现已损坏,但所有单例实现均已损坏。不要使用单例。
  • 您的代码从未真正注册您的回调。由于您的instance() 函数返回callback_store 对象的临时副本,因此您的注册数据进入该临时副本,然后立即销毁。实际的“主要”单例对象 static callback_store instance 永远不会在其中注册任何内容。

标签: c++ c++11 lambda callable std-function


【解决方案1】:

我认为问题在于您实现单例类的方式。

public:
static callback_store instance()
{
    static callback_store instance;
    return instance;
}

您正在返回静态对象的副本,而应该使用

public:
static callback_store& instance()
{
    static callback_store instance;
    return instance;
}

您的代码的输出将被(测试):

Hello World
register_callback() <<<
register_callback() func() 
do_test() invoked !!
register_callback() m_func() 
do_test() invoked !!
register_callback() :: ZN4TestC4EvEUlvE_
invoke_callback() <<< 
do_test() invoked !!
destructor

【讨论】:

    【解决方案2】:

    instance() 成员函数应该返回 callback_store&

    【讨论】:

    • 一个解释会很好,如果你可以添加一个:) 另外,你应该包括额外的信息,也许链接到文档?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    相关资源
    最近更新 更多