Ответ 1
ADL не используется, когда задействованы явные аргументы шаблона, если вы не введете объявление функции шаблона в точке вызова. Вы используете неквалифицированную форму get
с использованием нетипичного аргумента шаблона 0
, поэтому вам нужно ввести объявление функции шаблона или использовать квалифицированную версию get
как std::get<0>(ar)
.
В стандарте [temp.arg.explicit]/8
: (выделение мое)
[Примечание: для простых имен функций, зависящий от аргумента поиск (6.4.2) применяется, даже если имя функции не отображается в рамках вызова. Это связано с тем, что вызов по-прежнему имеет синтаксическую форму вызова функции (6.4.1). Но когда используется шаблон функции с явными аргументами шаблона, вызов не имеет правильной синтаксической формы, если в точке вызова не отображается шаблон функции с таким именем. Если такого имени не видно, вызов не является синтаксически правильно сформированным, и поиск, зависящий от аргумента, не применяется. Если какое-то такое имя является видимым, применяется поиск, зависящий от аргумента, и дополнительные шаблоны функций могут быть найдены в других пространствах имен.
РЕДАКТИРОВАТЬ:
Как указал в комментарии @Yakk - Адам Невраумонт, без присутствия объявления функции шаблона выражение get<0>(ar)
будет проанализировано как (get<0)>(ar)
, то есть как серия выражения сравнения вместо вызова функции.