In the Boost.Intrusive docs in the chapter "When to use?" https://www.boost.org/doc/libs/1_72_0/doc/html/intrusive/usage_when.html, it is stated that you can use intrusive containers containing objects of different or unknown size.
#include <boost/intrusive/list.hpp>
using namespace boost::intrusive;
//An abstract class that can be inserted in an intrusive list
class Window : public list_base_hook<>
{
public:
//This is a container those value is an abstract class: you can't do this with std::list.
typedef list<Window> win_list;
//A static intrusive list declaration
static win_list all_windows;
//Constructor. Includes this window in the list
Window() { all_windows.push_back(*this); }
//Destructor. Removes this node from the list
virtual ~Window() { all_windows.erase(win_list::s_iterator_to(*this)); }
//Pure virtual function to be implemented by derived classes
virtual void Paint() = 0;
};
//The static intrusive list declaration
Window::win_list Window::all_windows;
//Some Window derived classes
class FrameWindow : public Window
{ void Paint(){/**/} };
class EditWindow : public Window
{ void Paint(){/**/} };
class CanvasWindow : public Window
{ void Paint(){/**/} };
//A function that prints all windows stored in the intrusive list
void paint_all_windows()
{
for(Window::win_list::iterator i(Window::all_windows.begin())
, e(Window::all_windows.end())
; i != e; ++i)
i->Paint();
}
//...
//A class derived from Window
class MainWindow : public Window
{
FrameWindow frame_; //these are derived from Window too
EditWindow edit_;
CanvasWindow canvas_;
public:
void Paint(){/**/}
//...
};
//Main function
int main()
{
//When a Window class is created, is automatically registered in the global list
MainWindow window;
//Paint all the windows, sub-windows and so on
paint_all_windows();
//All the windows are automatically unregistered in their destructors.
return 0;
}
My problem is that I don't understand when someone would need that (example of usage?). And I dont understand which part in the given example shows this behaviour and why you cannot do this with standard containers.
They have measured the performance of their program, and found that the slowdown of using
std::vector<Window *>
over this is unacceptable. The given example shows a "how to", it isn't an example of the "when to".You can't have a
std::vector<Window>
(norstd::list<Window>
etc), becauseWindow
is an abstract type. Thestd::
containers own theWindow
objects they contain, having allocated space for them.The intrusive list works because the
boost::intrusive::list_base_hook
base contains the prev / next pointers, and the objects contain the hook. That means theWindow
objects can live anywhere, e.g. inmain
as the example withMainWindow window
and it's memberWindows
.