2014-03-03 58 views
1

玩弄模板和专门知识试图了解规则我使用了下面的代码。如何解释函数模板解析?

template <typename T> // A 
void foo(T); 

template <typename T> // B 
void foo(T *); 

template <> 
void foo<int *>(int *); // C 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int n=0; 
    int *p = &n; 
    foo(p); 

    return 0; 
} 

你认为哪个版本的foo会在这里被调用?我期待着C,但那不是什么情况。它实际上是B.但为什么呢? B不是C的最佳匹配和专业化吗?

但是,如果我改变C到

template <> 
void foo<>(int *) // C 

template <> 
void foo<int>(int *) // C 

然后把foo()调用得到解决到C?因此,我不完全理解void foo <>中的斜角括号之间的语法和含义。

希望有人澄清这一点。

谢谢。

回答

1

C不是B的专门化。C中的尖括号之间的实体int*是模板参数T的值。如果你专门研究A,那么T需要和参数的类型一样。如果您专门研究B,则参数需要为T*,而不是T

当您更改C的声明

template <> 
void foo<int>(int *) // C 

C为B的专业化,但不是A,通过同样的道理。

在这两种情况下,B都胜过超负荷分辨率。在第一种情况下,B没有明确的专门化,所以B被调用。在第二种情况下,C的显式特化被调用。

+0

抱歉密集。我仍然困惑。我几乎从一开始就被抛弃了。 “int *是参数T的值”是什么意思?你能澄清一下吗? – driftwood

+0

当您专门化模板函数时,您将声明具有给定的所有模板参数值的函数。当你输入'template <> foo (int *)'时,你所说的是'T'是'int *'。 – Brian

+0

好的我认为在你原来的陈述中让我感到困惑的是,如果你专门研究A,那么T需要和参数的类型相同,如果你'专精B,那么参数需要是T *,而不是T.“ – driftwood