- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
考虑这段代码:
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/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!