c ++: контекст поиска безоговорочного имени в шаблоне

Я попытался проконсультироваться со стандартом по разрешению do_run и обнаружил, что «Для части поиска используется только поиск по неквалифицированному имени (3.4.1) или поиск по квалифицированному имени (3.4.3).
найдены объявления функций из контекста определения шаблона «. Что такое контекст?

В следующем примере do_run(int) как-то «прячется» do_run(domain::mystruct)и компилятор жалуется что o can't be converted to int, Если я закомментирую do_run(int), do_run(domain::mystruct) становится видимым для runи код скомпилирован. Относится ли это поведение к «контексту», указанному в стандарте? Кажется мне обоим do_run(int) а также do_run(domain::mystruct) должен быть видимым для (разрешимого) запуска.

namespace domain {
struct mystruct { };
}

void do_run(domain::mystruct) { cout << "do_run(domain::mystruct)" << endl; }

namespace lib { namespace details {

template <class T>
class runner {
public:
void run(T t) { do_run(t); }
};

void do_run(int) { cout << "do_run(int)" << endl; }
}}

int main() {
domain::mystruct o;
lib::details::runner<domain::mystruct> r;
r.run(o);
return 0;
}

В присутствии do_run(int)Мне нужен дополнительный шаг, чтобы принести do_run(domain::mystruct) в «контекст». Есть три способа:

  1. положил do_run(domain::mystruct) в домене пространства имен.
  2. положил do_run(domain::mystruct) в пространстве имен lib :: details.
  3. добавлять using ::do_run внутри пространства имен lib :: details.

Итак, я вывел контекст, это пространство имен lib :: details и namespace domain?

Компилятор VS2010

3

Решение

Поиск зависит от того, является ли это зависимым именем или нет. Так как вызов вашей функции зависит от типа аргумента шаблона T (через вызов с использованием объекта t этого типа), это зависимое имя.

Независимые имена просто ищутся в контексте, где определен шаблон. Все, что связано с фактической реализацией, не принимается во внимание: поскольку имя определяется как не зависящее от аргумента шаблона, было бы нецелесообразно принимать это во внимание. Это этап I поиска.

Имена зависимых функций ищутся с учетом экземпляров. При этом используются все аргументы и определяются связанные пространства имен для поиска функций только в этих связанных пространствах имен. Для встроенных типов добавленное связанное пространство имен является глобальным пространством имен. Для других типов добавленные связанные пространства имен являются пространством имен, в котором они живут, а также всем включенным пространством имен. Кроме того, добавляется связанное пространство имен вещей, видимых из определения класса: ассоциированные пространства имен базовых классов, для шаблонов пространства имен аргументов шаблона и т. Д. Это поиск фазы II, также называемый зависимый от аргумента поиск (Я думаю, что термины не совсем идентичны, и детали, конечно, не так просты, как описано выше).

В приведенном вами коде do_run() функция в глобальном масштабе, очевидно, найдена для lib::details::runner<domain::mystruct> как это происходит в глобальном пространстве имен. Было бы также найдено, если бы он был перемещен в domain, do_run() метод в пространстве имен lib::details является не найдено в инстанции lib::details::runner<int>однако: связанные пространства имен для int являются только глобальным пространством имен, но функции там нет, и она не просматривается до момента ее создания, потому что это зависимое имя.

Тем не менее, я понимаю, что MSVC ++ не реализует двухфазный поиск имени так, как он указан, но я не знаю, каким образом он отклоняется.

1

Другие решения

Других решений пока нет …