I have always been reading that using this code is not so good:
std::vector<T> my_vector;
...
std::sort(my_vector.begin(), my_vector.end());
It is better to write it as:
std::vector<T> my_vector;
...
std::sort(std::begin(my_vector), std::end(my_vector));
Because std::begin will work with all containers including normal arrays.
What is the alternative to my_vector.size()
that will work for all containers including normal arrays?
Most commonly, containers are around 10-feet, 20-feet, or 40-feet long, each at around 8 feet wide. The height of each shipping container varies between standard height (8 feet 6 inches) and "high cube" (9 feet 6 inches), which are often used to increase storage space or create better air circulation.
Ideally, we can divide 0.630 m³ (the single packing box volume) into 28 m³ (fittable cubic meters of a 20 ft container), and the answer is 44 (boxes). This result is obtained without considering the matching of box size and container size.
Shippers must adhere to ISO specifications in order to ensure their shipping containers fit available transport systems in different places around the world. Shipping containers today frequently occur in two main sizes: Standard containers: 8′ wide by 8’6″ high and 20′ or 40′ in length; or
Dry containers commonly used internationally include: 20GP – the external dimension 20ft x 8ft x 8.5ft 40GP – the external dimension 40ft x 8ft x 8.5ft 40HC – the external dimension 40ft x 8ft x 9.5ft
Actually using std::begin(my_vector)
is not the Right Thing! If you want to pick up the customization point you'd rather use
using std::begin;
using std::end;
std::sort(begin(cont), end(cont));
This approach tries to find begin(cont)
using ADL and, when failing to locate a suitable versio, fallback to use std::begin
.
Sadly, there is no std::size
being the default for a customization point like std::begin
. It would sort of work to use std::distance()
:
std::distance(begin(cont), end(cont));
However, for typical node-based containers or, more generally, for non-random access iterators this approach would walk the elements rather then obtaining the size from a stored value. Thus, I'd think you'd want to call cont.size()
. It would be relatively straight forward to define a suitable customization point:
namespace util {
template <typename C>
typename C::difference_type size(C const& c) {
return c.size();
}
template <typename T, std::size_t N>
std::size_t size(T const(&)[N]) {
return N;
}
}
As was pointed out in comments, a non-member size()
function was added to the working paper for C++17 (see the bottom of the synopsis in 24.3 [iterator.synoposis]). N4280 is the paper which proposed the change. This paper also proposes functions empty()
and data()
which were also added. All of these functions are declared in <iterator>
.
The version added to C++17 uses a decltype()
on the size()
member directly in the return type. In addition it declares the function to be constexpr
:
template <typename C>
constexpr auto size(C const& c) -> decltype(c.size()) {
return c.size();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With