Ответ 1
Фактически использование std::begin(my_vector)
- это не правильная вещь! Если вы хотите выбрать пункт настройки, вы предпочитаете использовать
using std::begin;
using std::end;
std::sort(begin(cont), end(cont));
Этот подход пытается найти begin(cont)
с помощью ADL и, если не удается найти подходящую версию, откажитесь от использования std::begin
.
К сожалению, нет значения std::size
для точки настройки, например std::begin
. Было бы неплохо использовать std::distance()
:
std::distance(begin(cont), end(cont));
Однако для типичных контейнеров на основе node или, в более общем плане, для итераторов неслучайного доступа этот подход будет перемещаться по элементам, а затем получать размер от сохраненного значения. Таким образом, я думаю, вы бы хотели называть cont.size()
. Было бы относительно просто определить подходящую точку настройки:
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;
}
}
Как отмечалось в комментариях, в рабочий документ для С++ 17 была добавлена функция non-member size()
(см. нижняя часть синопсиса в 24.3 [итератор.синопоз]). N4280 - это документ, в котором предлагается изменение. В этой статье также предлагаются функции empty()
и data()
, которые также были добавлены. Все эти функции объявлены в <iterator>
.
Версия, добавленная в С++ 17, использует decltype()
в элементе size()
непосредственно в возвращаемом типе. Кроме того, он объявляет функцию constexpr
:
template <typename C>
constexpr auto size(C const& c) -> decltype(c.size()) {
return c.size();
}