Search code examples
c++c++11shared-ptrconst-correctness

Why doesn't shared_ptr<A> implicit convert to shared_ptr<A const>?


I tried to introduce some const correctness (actually functional paradigms) to some new code and found that I cannot pass an std::shared_ptr<A> to a function that expects an std::shared_ptr<A const>. Note that I don't want to cast away constness but introduce it, which is legal with raw pointers.

Is there some way to get around this? I didn't find a member-function to do this.


The precise error uttered by g++ 4.6.1 is:

error: no matching function for call to ‘foo(std::shared_ptr<A>)’
note: candidate is:
note: template<class T> std::shared_ptr<_Tp> foo(std::shared_ptr<const _Tp>)

Solution

  • The problem in your case is not with the possible conversions from/to different std::shared_ptr, but is more related to how type inference works for template functions.

    When the compiler tries to match a function call with a template, it will only accept exact matches, i.e. no type conversions at all. In this case, your function takes a std::shared_ptr<const T>, and the caller has a std::shared_ptr<U> where U is not const. Because the match is not exact, it will discard the template and pick the next overload candidate.

    The simple workarounds are: avoid type inference altogether and provide the template argument:

    std::shared_ptr<A> p;
    foo<A>(p);             // will use the templated shared_ptr conversion
    

    Or perform the conversion yourself:

    foo(std::shared_ptr<const A>(p));