C++ 模板符号搜索问题

C++ 模板符号搜索问题,c++,C++,我有一个模板的问题,我不能真正理解 文件1: namespace A { template <typename T> void foo(T value) { ... } } // A 名称空间A { 模板 无效foo(T值) { ... } }//A 文件2: namespace B { template <typename Type> class Object { ... void bar(const Object& other) {

我有一个模板的问题,我不能真正理解

文件1:

namespace A
{

template <typename T>
void foo(T value)
{
    ...
}

} // A
名称空间A
{
模板
无效foo(T值)
{
...
}
}//A
文件2:

namespace B
{

template <typename Type>
class Object
{
    ...

void bar(const Object& other)
{
    ...
    B::foo(other);
    ...
}
    ...
};

template <typename Type>
void foo(Object<Type> value)
{
    ...
}

} // B
名称空间B
{
模板
类对象
{
...
空心条(常量对象和其他)
{
...
B::富(其他);
...
}
...
};
模板
void foo(对象值)
{
...
}
}//B
一般来说:我在一个名称空间中有模板函数,在另一个名称空间中有专门的函数(A::foo和B::foo)。 如果我试图像上面的代码片段那样编译它,那么它就会失败,因为它找不到 正确的foo函数。没关系。 但若我在调用foo之前删除名称空间解析,那个么它将编译并(!!!)调用适当的B::foo函数。怎么可能呢?
我同时检查了gcc和clang。

当您删除
B::
限定时,调用
foo(object)
可以通过(ADL)找到
B::foo

ADL用于使用非Qalified函数名的函数调用,并搜索和函数调用中的参数类型相关联的名称空间。由于
object
属于
object
类型,它位于命名空间
B
中,因此ADL搜索
B
,并找到
B::foo


剩下的问题是为什么
foo
的查找会推迟到实例化,而
B::foo
的查找则不会。原因是标准中有明确的规则(C++14.6.2/1)。在模板内部,如果任何参数依赖于模板参数,则在实例化之前,使用非限定名称的函数调用将保持未解析状态。这确实是您的情况,因为
对象
的类型为
对象
,所以它取决于模板参数
类型

专门化应该与模板出现在同一命名空间中。这不是专门化,而是单独的重载。请创建一个。感谢您的完整回答。