出乎我的意料,这个程序的工作原理:
#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
验证在线编译器:
- GCC 4.8
- 铛3.4
如果的instantation func<T>
在体内发生main
然后我会期望a::do_func
和b::do_func
尚未宣布。
这可怎么工作的?
更新
据@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]
铛++ 3.4 :
error: call to function 'do_func' that is neither
visible in the template definition nor found by
argument-dependent lookup
如此看来,函数模板和ADL的组合是必需的,使其工作。
不过,我不明白为什么会是这样..