简体   繁体   English

为什么不专门化 function 模板? (问答)

[英]Why not specialize function templates? (Q&A)

I will try to organize this problem alas Q&A and hope that there will be colleagues who will take something from this.我将尝试组织这个问题,作为问答,并希望有同事能从中有所收获。

First, lets answer at first glance a simple question, what is the output of this program?首先先回答一个简单的问题,这个程序的output是什么?

#include <iostream>

template<class T>
void f(T) { std::cout << 1; }

template<>
void f<>(int*) { std::cout << 2; }

template<class T>
void f(T*) { std::cout << 3; }

int main() {
    int *p = nullptr; 
    f( p );
}

If your answer was 3, congratulations, you are free to skip this Q&A.如果您的答案是 3,那么恭喜,您可以跳过此问答。

For everybody else:对于其他所有人:

I personally thought that the output should be 2, if you got to this point, I guess you too.我个人认为output应该是2,如果你到了这一步,我猜你也是。
Now lets dive a bit deeper.现在让我们深入一点。

The name f is overloaded by the two function templates void f(T) and void f(T*) .名称 f 被两个 function 模板void f(T)void f(T*)重载。 Note that overload resolution only considers the function templates, not the explicit specialisation void f<>(int*) , For overload resolution, first we deduce the template arguments for each function template, and get T = int * for the first one, and T = int for the second.注意,重载解析只考虑 function 模板,而不是显式特化void f<>(int*) ,对于重载解析,首先我们为每个 ZC1C425268E68385D1AB5074D1AB507E6FB4DABD882E7DZ 推导出模板 arguments ,并得到 TTA 中的第一个T = int * F1AB5074 T = int第二个。

Both function templates are viable, but which one is best? function 模板都是可行的,但哪一个最好? According to [over.match.best]§16.3.3¶1 , a function template is a better match than another function template if it's more specialised:根据[over.match.best]§16.3.3¶1 ,如果 function 模板更专业,则它比另一个 function 模板更匹配:

a viable function F1 is defined to be a better function than another viable function F2 if (...) the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 17.5.6.2 a viable function F1 is defined to be a better function than another viable function F2 if (...) the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 17.5.6.2

The process of partial ordering is a bit long to quote here, and not key to this question.部分排序的过程在这里引用有点长,并不是这个问题的关键。 But in summary, anything accepted by f(T*) would also be accepted by f(T) , but not the other way around.但总而言之, f(T*)接受的任何内容也将被f(T)接受,但反之则不然。 So f(T*) is more specialised.所以f(T*)更专业。

Now we know that the function template void f(T*) is selected by overload resolution, and we can start thinking about specialisations.现在我们知道 function 模板void f(T*)是通过重载决议选择的,我们可以开始考虑专门化。 Which of the function templates is void f<>(int*) a specialisation of?哪个 function 模板是void f<>(int*)的特化? [temp.expl.spec]§17.7.3¶3 : [temp.expl.spec]§17.7.3¶3

A declaration of a function template (...) being explicitly specialized shall precede the declaration of the explicit specialization.显式特化的 function 模板 (...) 的声明应在显式特化的声明之前。

So the explicit specialisation void f<>(int*) is a specialisation of void f(T) , since that's the only function template declaration that precedes it.因此,显式特化 void f<>(int*)void f(T)的特化,因为这是在它之前的唯一 function 模板声明。 Overload resolution however selected the other function template, void f(T*) , and we instead call an implicitly instantiated a specialisation of that, printing 3.然而,重载分辨率选择了另一个 function 模板void f(T*) ,我们改为将其称为隐式实例化的特化,打印 3。

For more, please refer to Herb Sutter's article更多内容请参考 Herb Sutter 的文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM