(C++) const is not deep

February 24, 2017 · View on GitHub

 

 

 

 

 

(C++) const is not deep

 

The meaning of 'const is not deep' can be viewed in the example below:

 


#include <vector> #include <boost/shared_ptr.hpp> struct Widget {   Widget(const int x) : mX(x) {}   int mX; }; struct WidgetManager {   WidgetManager()   {     mV.push_back(boost::shared_ptr<Widget>(new Widget(69)));   }   //A getter?   const std::vector<boost::shared_ptr<Widget> > GetWidgets() const { return mV; } private:   std::vector <boost::shared_ptr<Widget> > mV; }; int main() {   const WidgetManager m; //Cannot modify WidgetManager   m.GetWidgets()[0]->mX = 0; //CAN modify a Widget of a const WidgetManager! }

 

The desired and proper getter of WidgetManager should be the following, in which the Widgets themselves are also const:

 


struct WidgetManager {   const std::vector<boost::shared_ptr<const Widget> >& GetWidgets() const { return mV; }   //... };

 

The compiler, however, states that is cannot add const to the Widget:

 


[C++ Error] Unit1.cpp(51): E2034 Cannot convert 'const _STL::vector<boost::shared_ptr<Widget>,_STL::allocator<boost::shared_ptr<Widget> > >' to '_STL::vector<boost::shared_ptr<const Widget>,_STL::allocator<boost::shared_ptr<const Widget> > >'

 

The solution is to write a function to add const yourself:

 


template <class T> const std::vector <boost::shared_ptr<const T> > AddConst(   const std::vector <boost::shared_ptr<T> > v) {   return std::vector <boost::shared_ptr<const T> >(v.begin(),v.end()); }

 

The function needs to be called in the getter member function as shown below. Note that the getter cannot return a reference to the original Widgets anymore.

 


struct WidgetManager {   const std::vector <boost::shared_ptr<const Widget> > GetWidgets() const { return AddConst(mV); }   //... };