gpt4 book ai didi

C++ 函数模板特化和重载

转载 作者:搜寻专家 更新时间:2023-10-31 01:31:55 25 4
gpt4 key购买 nike

考虑这段代码:

template <class T>
void f(T p) { //(1)
cout << "Second" << endl;
}

template <>
void f(int *p) { //(2)
cout << "Third" << endl;
}


template <class T>
void f(T* p) { //(3)
cout << "First" << endl;
}

调用如 int *p; f(p); 将输出 First

如果声明的顺序改变了,像这样:

template <class T>
void f(T* p) { //(3)
cout << "First" << endl;
}


template <class T>
void f(T p) { //(1)
cout << "Second" << endl;
}

template <>
void f(int *p) { //(2)
cout << "Third" << endl;
}

相同的调用 (int *p; f(p);) 将输出 Third

我了解了函数模板重载解析发生的方式:首先,解析仅考虑非模板函数底层基本模板。在选择了“最专门化”的函数之后,如果它是一个模板函数并且它对推导(或明确指定)的参数具有专门化,则调用该专门化。

现在我的问题是:如何确定函数是哪个底层基本模板的特化?在我的示例中,哪个函数模板重载( (1) 或 (3) )是 (2) 特化?

我的猜测是,当声明一个特化时,已经声明的模板被考虑,并从那些最“特化”(其参数“最接近”这个特化)的模板中被选择。它是否正确?另外,您能否指出标准中指定的位置?

最佳答案

它打印“First”,因为声明的顺序会影响您实际专门化的模板。

您的示例有两个函数模板,它们重载了相同的名称。在第一种情况下,您特化了 void f(T p),因为它是目前为止看到的唯一模板。

在第二种情况下,void f(T* p) 是特化的。所以是的,你的猜测是正确的。具体在[temp.deduct.decl/1] :

In a declaration whose declarator-id refers to a specialization of a function template, template argument deduction is performed to identify the specialization to which the declaration refers. Specifically, this is done for explicit instantiations, explicit specializations, and certain friend declarations. [...]

这包括函数模板的部分排序。但是,部分排序仅适用于在您引入特化时可用的函数模板声明。

标准在 [temp.expl.spec/7] 发出警告:

The placement of explicit specialization declarations for function templates, [...] , can affect whether a program is well-formed according to the relative positioning of the explicit specialization declarations and their points of instantiation in the translation unit as specified above and below. When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation.

关于C++ 函数模板特化和重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44624289/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com