Соответствующая часть стандарта - 6.5.4 / 1:
, если _RangeT является типом класса, начальные и конечные объекты неквалифицированных фидов рассматриваются в области класса _RangeT как если через поиск доступа к члену класса (3.4.5), и если либо (или оба) найдут хотя бы одно объявление, begin-expr и end-expr будут
__range.begin()
и__range.end()
соответственно;- в противном случае begin-expr и end-expr -
blockquote>begin(__range)
иend(__range)
соответственно, где начальный и конечный объекты просматриваются с зависимым от аргумента поиска (3.4.2). Для целей поиска этого имени пространство имен std является ассоциированным пространством имен.Итак, вы можете выполнить любое из следующих действий:
- define
begin
иend
функции-член- определяют
begin
иend
свободные функции, которые будут найдены ADL (упрощенная версия: поместите их в то же пространство имен, что и класс)- specialize
std::begin
иstd::end
std::begin
все равно вызывает функцию-членbegin()
, поэтому, если вы выполняете только одно из указанных выше, то результаты должны быть одинаковыми независимо от того, который вы выбираете. Это те же самые результаты для циклов, основанных на диапазонах, а также тот же результат для простого смертного кода, который не имеет собственных магических правил разрешения имен, поэтому толькоusing std::begin;
следует безусловный вызовbegin(a)
.Если вы реализуете функции-члены и , то функции ADL, тем не менее, тогда петли на основе диапазона должны вызывать функции-члены, тогда как простые смертные будут вызывать функции ADL.
Если вещь, которую вы пишете, реализует интерфейс контейнера, тогда она будет иметь функции
begin()
иend()
, которые должны быть достаточными , Если это диапазон, который не является контейнером (что было бы неплохо, если бы оно было неизменным или если вы не знаете размер вверх), вы можете выбирать.Варианты вы выложите, обратите внимание, что вы не должны перегружать
std::begin()
. Вам разрешено специализировать стандартные шаблоны для пользовательского типа, но помимо этого, добавление определений в пространство имен std является неопределенным поведением. Но в любом случае специализированные стандартные функции являются плохим выбором, хотя бы потому, что отсутствие специализации частичных функций означает, что вы можете делать это только для одного класса, а не для шаблона класса.