Вопреки моим ожиданиям, эта программа работает:
#include <iostream>
namespace a { struct item{}; }
namespace b { struct item{}; }
template<typename T>
void func(T t) { do_func(t); }
int main()
{
func(a::item{});
func(b::item{});
}
namespace a { void do_func(item) { std::cout << "a::func\n"; } }
namespace b { void do_func(item) { std::cout << "b::func\n"; } }
Вывод:
a::func
b::func
Проверки с онлайн-компиляторами:
Если представление func<T>
происходит в теле main
, я бы ожидал, что a::do_func
и b::do_func
еще не объявлены.
Как это работает?
Update
Согласно @Marc Claesen, причина, по которой выше:
создается экземпляр шаблона после прочтения всего источника
Однако, почему этот код не работает:
#include <iostream>
template<typename T>
void func(T t) { do_func(t); }
int main()
{
func(1);
}
void do_func(int) { std::cout << "do_func(int)\n"; }
Смотрите gcc-4.8:
error: 'do_func' was not declared in this scope,
and no declarations were found by argument-dependent
lookup at the point of instantiation [-fpermissive]
error: call to function 'do_func' that is neither
visible in the template definition nor found by
argument-dependent lookup
Итак, кажется, что комбинация шаблона функции и ADL необходимы, чтобы заставить ее работать.
Однако я не понимаю, почему это так.