【问题标题】:smart pointer as argument of function which uses std::function, std::bind智能指针作为使用 std::function、std::bind 的函数的参数
【发布时间】:2021-08-29 21:36:37
【问题描述】:
#include <functional>
#include <iostream>
#include <memory>

template <typename T>
struct Message
{
    T a;
};

template <typename T>
class Connection : public std::enable_shared_from_this<T>
{
  typedef std::function<void(Message<T>&)> msg_handle;
  public:
    void SetHandle(msg_handle handle)
    {
      handle_ = handle;
    }
    void Run()
    {
      Message<T> t;
      std::cout << "Run() from Connection" << std::endl;
      handle_(t);
    }

  private:
    msg_handle handle_;
};

template <typename T>
class Server
{
  public:
    void OnMessage(Message<T>& msg, std::shared_ptr<Connection<T>> remote)
    {
      std::cout << "OnMessage() from Server" << std::endl;
    }
};


int main()
{
  std::shared_ptr<Server<int>> server = std::make_shared<Server<int>>();
  std::shared_ptr<Connection<int>> connection = std::make_shared<Connection<int>>();
  connection->SetHandle(std::bind(&Server<int>::OnMessage, server, std::placeholders::_1, connection));
  connection->Run();
  return 0;
}

错误:

E:\Qt\Tools\mingw730_64\lib\gcc\x86_64-w64-mingw32\7.3.0\include\c++\bits\shared_ptr.h:661: error: no matching function for call to 'std::weak_ptr<int>::_M_assign(Connection<int>*&, const std::__shared_count<>&)'
In file included from E:/Qt/Tools/mingw730_64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/memory:81:0,
                 from C:/Boost/include/boost-1_72/boost/asio/associated_allocator.hpp:19,
                 from C:/Boost/include/boost-1_72/boost/asio.hpp:20,
                 from D:\StudyDisk\Applications\QT\test_boost_connection\main.cpp:2:
E:/Qt/Tools/mingw730_64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/shared_ptr.h: In instantiation of 'void std::enable_shared_from_this<_Tp>::_M_weak_assign(_Tp1*, const std::__shared_count<>&) const [with _Tp1 = Connection<int>; _Tp = int]':
E:/Qt/Tools/mingw730_64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/shared_ptr_base.h:1373:6:   required from 'typename std::enable_if<std::__shared_ptr<_Tp, _Lp>::__has_esft_base<_Yp2>::value>::type std::__shared_ptr<_Tp, _Lp>::_M_enable_shared_from_this_with(_Yp*) [with _Yp = Connection<int>; _Yp2 = Connection<int>; _Tp = Connection<int>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2; typename std::enable_if<std::__shared_ptr<_Tp, _Lp>::__has_esft_base<_Yp2>::value>::type = void]'
E:/Qt/Tools/mingw730_64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/shared_ptr_base.h:1301:35:   required from 'std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<Connection<int> >; _Args = {}; _Tp = Connection<int>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]'
E:/Qt/Tools/mingw730_64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/shared_ptr.h:344:64:   required from 'std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<Connection<int> >; _Args = {}; _Tp = Connection<int>]'
E:/Qt/Tools/mingw730_64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/shared_ptr.h:690:14:   required from 'std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = Connection<int>; _Alloc = std::allocator<Connection<int> >; _Args = {}]'
E:/Qt/Tools/mingw730_64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/shared_ptr.h:706:39:   required from 'std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = Connection<int>; _Args = {}]'
D:\StudyDisk\Applications\QT\test_boost_connection\main.cpp:50:83:   required from here
E:/Qt/Tools/mingw730_64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/shared_ptr.h:661:4: error: no matching function for call to 'std::weak_ptr<int>::_M_assign(Connection<int>*&, const std::__shared_count<>&)'
  { _M_weak_this._M_assign(__p, __n); }
    ^~~~~~~~~~~~

我不明白。请帮忙!!!

【问题讨论】:

  • 错字? ->std::enable_shared_from_this&lt;Connection&lt;T&gt;&gt;Demo
  • 请修剪您的代码,以便更容易找到您的问题。请按照以下指南创建minimal reproducible example。

标签: c++ shared-ptr enable-shared-from-this


【解决方案1】:

std::enable_shared_from_this 要求您指定要启用且正在派生的类的类型。

当你启用的类是Connection&lt;T&gt;时,你错误地指定了T。

错误是(间接)指出隐藏的weak_ptr 成员的类型错误。

简单地说,这需要是你的类模板定义

template <typename T>
class Connection : public std::enable_shared_from_this<Connection<T>>
{
//...
};

【讨论】:

    【解决方案2】:

    您误用了std::enable_shared_from_this。它的模板参数需要是从它派生的类型,即Connection&lt;T&gt;,但您只传递T。

    所以,改变这个:

    template <typename T>
    class Connection : public std::enable_shared_from_this<T>
    

    到这里:

    template <typename T>
    class Connection : public std::enable_shared_from_this<Connection<T>>
    

    不过,话虽如此,在这段代码中根本没有理由使用std::enable_shared_from_this,因为没有任何东西试图在connection 对象上使用shared_from_this() 或weak_from_this()。

    此外,任何时候您想使用 std::bind(),请考虑使用 lambda。

    试试这个:

    #include <functional>
    #include <iostream>
    #include <memory>
    
    template <typename T>
    struct Message
    {
        T a;
    };
    
    template <typename T>
    class Connection
    {
      typedef std::function<void(Message<T>&)> msg_handle;
    
      public:
        void SetHandle(msg_handle handle)
        {
          handle_ = handle;
        }
    
        void Run()
        {
          Message<T> t;
          std::cout << "Run() from Connection" << std::endl;
          handle_(t);
        }
    
      private:
        msg_handle handle_;
    };
    
    template <typename T>
    class Server
    {
      public:
        void OnMessage(Message<T>& msg, std::shared_ptr<Connection<T>> remote)
        {
          std::cout << "OnMessage() from Server" << std::endl;
        }
    };
    
    
    int main()
    {
      auto server = std::make_shared<Server<int>>();
      auto connection = std::make_shared<Connection<int>>();
      connection->SetHandle([=](auto& m){ server->OnMessage(m, connection); });
      connection->Run();
      return 0;
    }
    

    Online Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      • 1970-01-01
      相关资源
      最近更新 更多