Я попытался проконсультироваться со стандартом по разрешению 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)
в «контекст». Есть три способа:
do_run(domain::mystruct)
в домене пространства имен.do_run(domain::mystruct)
в пространстве имен lib :: details.using ::do_run
внутри пространства имен lib :: details.Итак, я вывел контекст, это пространство имен lib :: details и namespace domain?
Компилятор VS2010
Поиск зависит от того, является ли это зависимым именем или нет. Так как вызов вашей функции зависит от типа аргумента шаблона T
(через вызов с использованием объекта t
этого типа), это зависимое имя.
Независимые имена просто ищутся в контексте, где определен шаблон. Все, что связано с фактической реализацией, не принимается во внимание: поскольку имя определяется как не зависящее от аргумента шаблона, было бы нецелесообразно принимать это во внимание. Это этап I поиска.
Имена зависимых функций ищутся с учетом экземпляров. При этом используются все аргументы и определяются связанные пространства имен для поиска функций только в этих связанных пространствах имен. Для встроенных типов добавленное связанное пространство имен является глобальным пространством имен. Для других типов добавленные связанные пространства имен являются пространством имен, в котором они живут, а также всем включенным пространством имен. Кроме того, добавляется связанное пространство имен вещей, видимых из определения класса: ассоциированные пространства имен базовых классов, для шаблонов пространства имен аргументов шаблона и т. Д. Это поиск фазы II, также называемый зависимый от аргумента поиск (Я думаю, что термины не совсем идентичны, и детали, конечно, не так просты, как описано выше).
В приведенном вами коде do_run()
функция в глобальном масштабе, очевидно, найдена для lib::details::runner<domain::mystruct>
как это происходит в глобальном пространстве имен. Было бы также найдено, если бы он был перемещен в domain
, do_run()
метод в пространстве имен lib::details
является не найдено в инстанции lib::details::runner<int>
однако: связанные пространства имен для int
являются только глобальным пространством имен, но функции там нет, и она не просматривается до момента ее создания, потому что это зависимое имя.
Тем не менее, я понимаю, что MSVC ++ не реализует двухфазный поиск имени так, как он указан, но я не знаю, каким образом он отклоняется.
Других решений пока нет …