Ответ 1
Проблема не имеет ничего общего с ADL), но только с поиском имен. Проект концепций, используемый GCC, - n4377, но стандартный проект С++, который я буду использовать, - n4140. Во-первых, прежде чем погрузиться в стандартизацию, мы можем превратить вашу проблему в MCVE формы, которую, как мы знаем, должны работать. Пример:
template<typename T> concept bool C =
requires (T a, T b) {
a + b;
};
Это простое требование, [expr.prim.req.simple], которое проверяет достоверность выражения. Переписывая наш пример в соответствии с формой:
template<typename T> concept bool Drawable =
requires (const T& x) {
draw(x);
};
Мы можем видеть, что наш синтаксис прекрасен. Хорошо, что говорит n4377?
[expr.prim.req]/1 Требуемое выражение требует краткого выражать требования к аргументам шаблона. Требование - это требование, которое могут быть проверены путем поиска по имени (3.4) или путем проверки свойств типов и выражения.
[expr.prim.req]/6 Тело требования состоит из последовательности требования. Эти требования могут относиться к локальным параметрам, параметры шаблона и любые другие объявления, видимые из охватывающий контекст....
Имеет смысл. Мы знаем, что охватывающий контекст - это глобальное пространство имен, так что говорит n4140?
[basic.lookup.unqual]/1 Во всех случаях, перечисленных в 3.4.1, области ищут декларацию в порядке, указанном в каждом из соответствующие категории; поиск имени заканчивается, как только декларация найдено для имени. Если объявление не найдено, программа плохо сформирован.
Имя, используемое при определении функции, следующей за функциями declarator-id, который является членом пространства имен
N
(где, только для целей изложения,N
может представлять глобальную область), должно быть объявленного до его использования в блоке, в котором он используется, или в одном из его закрывающие блоки (6.3) или, должны быть объявлены до его использования в namespaceN
...
Поскольку концепция относится к функции, применяется параграф выше.