For historical reasons, wxWidgets uses custom container classes internally.
This was unfortunately unavoidable during a long time when the standard library wasn't widely available and can't be easily changed even now that it is for compatibility reasons. However, starting from version 3.3.0 these custom container classes are implemented in terms of the standard library classes by default and so are mostly interoperable with them.
This means that even if some wxWidgets function is documented as taking or returning a legacy container such as wxList<T> or wxArray<T>, you can work with them as if they were just std::list<T*>
or std::vector<T>
. For example, wxWidgets::GetChildren() is documented as returning a wxWindowList
, which inherits from std::list<wxWindow*>
and so can be used as such, e.g.
You may still need to create wxWidgets containers to pass them to some wxWidgets function, e.g. wxDir::GetAllFiles() requires a wxArrayString to be passed in. However in this case you may still the object as if it were just a std::vector<wxString>
and, other than that, there is no reason to use the container classes provided by wxWidgets anywhere in the new code, they only exist for backwards compatibility and standard library classes should be used by the application.
This section contains a brief overview of the legacy container classes and is mostly useful if you need to maintain an existing code base using them – none of this is really necessary to know if you follow the advice above and treat all wxWidgets containers as if they were standard containers.
All these classes use macro-based machinery to define type-safe classes based on the generic implementation. Generally speaking, this consists of using one macro to declare a particular "instantiation" and then another one to actually define it, e.g. WX_DECLARE_LIST() and WX_DEFINE_LIST() for the linked lists or WX_DECLARE_OBJARRAY() and WX_DEFINE_OBJARRAY() for the arrays containing objects. The array classes storing primitive types, such as int
, don't need to be declared and defined separately, and so only WX_DEFINE_ARRAY_INT() exists, without the matching "DECLARE" macro.
The "DECLARE" macro declares a new container class containing the elements of given type and can be used in a header file and don't require the full declaration of the contained type. The "DEFINE" macros must be used in a place where the full declaration of container element class is in scope (i.e. not just forward declaration).
Finally, wxWidgets predefines several commonly used container classes. wxList itself is defined for compatibility with very old versions of wxWidgets as a list containing wxObjects and wxStringList as a list of C-style strings (char *
). There are also a few predefined array classes including wxArrayInt, wxArrayLong, wxArrayPtrVoid and wxArrayString, similar to std::vector
instantiations for int
, long
, void*
and wxString
respectively.
Since wxWidgets 3.3.0, all legacy container classes are implemented in terms of the standard library classes. These implementations are mostly, but not completely, compatible with the implementation provided by wxWidgets itself which was used by default in the previous versions.
If the existing code doesn't compile with the implementation based on the standard containers, it's possible to rebuild the library to use the legacy implementation of them by setting wxUSE_STD_CONTAINERS option to 0. This is done by:
wx/msw/setup.h
file to change the option of this value there for wxMSW.--disable-std_containers
option when calling configure when building wxWidgets under Unix-like systems.-DwxUSE_STD_CONTAINERS=OFF
when using CMake build system.However a better approach is to update the legacy code to work with the new container classes implementation. In most cases this can be done in such a way that they still continue to work with the legacy implementation as well, thus allowing the application to compile with the default configurations of both wxWidgets 3.3 and 3.2 and even earlier versions.
Here are some modifications that may need to be done in order to make the existing compatible with the default build of wxWidgets 3.3:
wxList::compatibility_iterator
must be used instead of wxList::Node*
when iterating over the list contents. The compatibility_iterator
class has the same semantics as a Node
pointer but it is an object and not a pointer, so the old code doing WX_DEFINE_ARRAY_INT(bool)
cannot be used because of the differences in std::vector<bool>
specialization compared with the generic std::vector<> class. Please either use std::vector<bool>
directly or use wxArrayInt instead.