All the above answers mentioned C++11 and GCC, but not mention _GLIBCXX_USE_CXX11_ABI compile definition in GCC, this is not enough
- Compiled with -std=c++11 do not mean std::list::size() is O(1) in GCC, it's default O(1), but when compiled with _GLIBCXX_USE_CXX11_ABI=0, it's O(N)
- GCC version < 5.1, like GCC4.8 support C++11, but std::list::size() is O(N) no matter you use what compile flags.
.
This can be clearly be shown in current GCC source code:
size() is implement as below
_GLIBCXX_NODISCARD
size_type
size() const _GLIBCXX_NOEXCEPT
{ return _M_node_count(); }
It called _M_node_count(), and _M_node_count is implemented as below:
#if _GLIBCXX_USE_CXX11_ABI
static size_t
_S_distance(const_iterator __first, const_iterator __last)
{ return std::distance(__first, __last); }
// return the stored size
size_t
_M_node_count() const
{ return this->_M_get_size(); }
#else
// dummy implementations used when the size is not stored
static size_t
_S_distance(const_iterator, const_iterator)
{ return 0; }
// count the number of nodes
size_t
_M_node_count() const
{ return std::distance(begin(), end()); }
#endif
if _GLIBCXX_USE_CXX11_ABI is set to 0, the size() is O(N), in other case is O(1).
_GLIBCXX_USE_CXX11_ABI set to 0 will happen when you use a high version GCC compiled libraries and need link to a low version GCC compiled libraries, for example, your system have installed a GCC 4.8 compiled GTEST libraries, but your code now use GCC 7.3 and use C++11, and you need to link to that libraries, in this case you need to add following to your CMakeLists.txt, otherwise it will have link issue.
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
In a word, in GCC,
- When using GCC version < 5.1, std::list::size() is O(N)
- When using GCC version >= 5.1:
- when compiled with _GLIBCXX_USE_CXX11_ABI=0, std::list::size() is O(N)
- when compiled without _GLIBCXX_USE_CXX11_ABI set(default is 1) or with _GLIBCXX_USE_CXX11_ABI=1,
std::list::size() is O(1)