Difference between `const shared_ptr<T>` and `shared_ptr<const T>`?

You are right. shared_ptr<const T> p; is similar to const T * p; (or, equivalently, T const * p;), that is, the pointed object is const whereas const shared_ptr<T> p; is similar to T* const p; which means that p is const. In summary:

shared_ptr<T> p;             ---> T * p;                                    : nothing is const
const shared_ptr<T> p;       ---> T * const p;                              : p is const
shared_ptr<const T> p;       ---> const T * p;       <=> T const * p;       : *p is const
const shared_ptr<const T> p; ---> const T * const p; <=> T const * const p; : p and *p are const.

The same holds for weak_ptr and unique_ptr.


boost::shared_ptr<Bar const> prevents modification of the Bar object through the shared pointer. As a return value, the const in boost::shared_ptr<Bar> const means that you cannot call a non-const function on the returned temporary; if it were for a real pointer (e.g. Bar* const), it would be completely ignored.

In general, even here, the usual rules apply: const modifies what precedes it: in boost::shared_ptr<Bar const>, the Bar; in boost::shared_ptr<Bar> const, it's the instantiation (the expression boost::shared_ptr<Bar> which is const.


#Check this simple code to understand... copy-paste the below code to check on any c++11 compiler

#include <memory>
using namespace std;

class A {
    public:
        int a = 5;
};

shared_ptr<A> f1() {
    const shared_ptr<A> sA(new A);
    shared_ptr<A> sA2(new A);
    sA = sA2; // compile-error
    return sA;
}

shared_ptr<A> f2() {
    shared_ptr<const A> sA(new A);
    sA->a = 4; // compile-error
    return sA;
}

int main(int argc, char** argv) {
    f1();
    f2();
    return 0;
}