Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Size of unknown container

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?

like image 791
Humam Helfawi Avatar asked Oct 25 '15 11:10

Humam Helfawi


People also ask

What is the average size of a container?

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.

How many boxes fit in a 20 ft container?

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.

What are the ISO specifications for shipping containers?

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

What is the size of a 40 dry container?

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


1 Answers

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();
}
like image 132
Dietmar Kühl Avatar answered Oct 16 '22 05:10

Dietmar Kühl