Search code examples
c++c++11stlshared-ptrweak-ptr

No viable conversion std::weak_ptr to std::shared_ptr for method call


I am able to convert back and forth inline.

std::shared_ptr<sfg::Notebook> mNotebook = ...;
std::weak_ptr<sfg::Notebook> weakNotebook(mNotebook);
std::shared_ptr<sfg::Notebook> strongNotebook(weakNotebook);

When I attempt to pass it to a method, I get the error:

"No viable conversion between std::weak_ptr<sfg::Notebook> to std::shared_ptr<sfg::Notebook>."

I am calling the method normally, and the method looks like:

onNotebookLeftClick(weakNotebook);

void onNotebookLeftClick(std::shared_ptr<sfg::Notebook> notebook) {
}

I am using OS X (10.10.2).


Solution

  • The shared_ptr constructor you're trying to use is explicit.

    template< class Y >
    explicit shared_ptr( const std::weak_ptr<Y>& r );
    

    Your first example

    std::shared_ptr<sfg::Notebook> strongNotebook(weakNotebook);
    

    works because you're using direct initialization, which works with explicit constructors. You'd have the same problem if you used copy initialization instead

    std::shared_ptr<sfg::Notebook> strongNotebook = weakNotebook; // this will fail
    

    To fix your error, do one of the following

    onNotebookLeftClick(std::shared_ptr<sfg::Notebook>{weakNotebook});
    

    or

    onNotebookLeftClick(weakNotebook.lock());
    

    Note that there's a difference between the two methods. If the weak_ptr has expired, the first solution will throw std::bad_weak_ptr, while the second option will construct an empty shared_ptr in that case.