【问题标题】:How do you correctly use boost::make_shared_ptr?你如何正确使用 boost::make_shared_ptr?
【发布时间】:2010-03-11 05:57:32
【问题描述】:

这个简单的例子在 VS2K8 中编译失败:

    io_service io2;
    shared_ptr<asio::deadline_timer> dt(make_shared<asio::deadline_timer>(io2, posix_time::seconds(20)));

和这个一样:

shared_ptr<asio::deadline_timer> dt = make_shared<asio::deadline_timer>(io2);

错误是:

错误 C2664: 'boost::asio::basic_deadline_timer::basic_deadline_timer(boost::asio::io_service &,const boost::posix_time::ptime &)' : 不能从 'const boost::asio 转换参数 1 ::io_service' 到 'boost::asio::io_service &'

【问题讨论】:

    标签: c++ visual-studio-2008 visual-c++ boost boost-asio


    【解决方案1】:

    问题在于asio::deadline_timer 有一个构造函数,它需要对服务进行非常量引用。但是,当您使用make_shared 时,它的参数是const。也就是make_shared这部分是问题所在:

    template< class T, class A1 > // service is passed by const-reference
    boost::shared_ptr< T > make_shared( A1 const & a1 )
    {
        // ...
    
        ::new( pv ) T( a1 ); // but the constructor requires a non-const reference
    
        // ...
    }
    

    你可以做的是将服务包装成一个reference_wrapper,使用ref

    #include <boost/ref.hpp>
    
    asio::io_service io1;
    shared_ptr<asio::deadline_timer> dt = // pass a "reference"
        make_shared<asio::deadline_timer>(boost::ref(io1));
    

    这会获取您的实例,并将其放入一个对象中,该对象可以隐式转换为对您的实例的引用。然后,您基本上传递了一个对象表示对您的实例的非常量引用。

    这是有效的,因为reference_wrapper 确实存储了指向您的实例的指针。因此,它可以返回取消引用的指针,同时仍然是const

    【讨论】:

    • 太好了,谢谢!不知道 boost::ref 。它的创建部分是为了解决这类问题,还是有其他用途?
    • @Apple:几乎就是出于这个原因而设计的。例如,boost::thread 将为新线程复制其参数,但如果您想实际传递引用 boost::ref 也可以在那里工作。每当您想传递引用但该函数打算进行复制时,都会使用它。
    猜你喜欢
    • 2011-04-16
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多