为什么在具有相同签名的模板化和非模板化函数之间进行选择时没有歧义?
Why no ambiguity when choosing between templated and non-templated functions with same signatures?
以下代码传递断言:
int foo() { return 1; }
template<typename T>
int foo() { return 2; }
int main() {
assert( 1 == foo() );
assert( 2 == foo<int>() );
return 0;
}
但据我了解,根据C++11标准第13.3.3/1段:
[...]给定这些定义,一个可行的函数
F1
被定义为比另一个可行的函数更好的函数F2
如果对于所有参数i
,ICSi(F1)
不是比ICSi(F2)
更糟糕的转换序列,然后[...]F1
是非模板函数,F2
是函数模板专用化 [...]
它不应该,因为签名最终是相同的。那么,为什么在调用foo<int>()
时没有歧义呢?我错过了什么?
你引用的文本相当密集;你必须仔细阅读。"如果对于所有参数i
,F1 比 F2 更好,ICSi(F1) 不是一个比 ICSi(F2) 更差的转换序列" -- 这里是正确的,因为两个转换序列是相同的,因此,任何一个都不比另一个差。所以现在你转到最后一部分:">然后F1 是一个非模板函数,F2 是一个函数模板专用化"。这是真的,所以F1比F2更好。将foo()
和foo<int>()
分别替换为 F1 和 F2,规则说foo()
比foo<int>()
更好匹配。
哎呀,我回答了错误的问题。正如评论所指出的,问题是,为什么明确调用foo<int>()
不能解决foo()
?答案是,foo<int>()
是对显式模板实例化的调用,而不是对重载函数的调用。考虑:
template <class Ty>
void f(Ty) { }
void f(int);
void g(int);
f(3.14); // calls f<double> (overloaded function call)
f(1); // calls f(int) (overloaded function call)
f<int>(3.14); // calls f<int> (explicit call of template instantiation)
g(3.14); // calls g(int)
在此示例中,f<int>
是模板专用化的名称。它不是名为f
的通用函数,所以没有重载需要考虑,就像调用g(3.14)
一样。
相关文章:
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 引号之间匹配/不匹配,带有不可避免的引号和多行
- 计算所选行的总和
- 通过USB在PC和Arduino之间进行串行通信
- 正则表达式 获取两个换行符之间的文本
- 如果我在下面的代码中使用 list 而不是 vector,为什么在我尝试在迭代器之间执行减法的行中编译失败?
- Arduino上的串行和流之间有什么区别,以及如何实现序列
- 一条线和两行声明之间的差异
- ESP8266和ATMEGA328P之间的串行通信
- 如何从 gtkmm 树视图中获取所选行
- openssl rc4 命令行加密和 cpp 文件实现 rc4 之间的区别
- 如何在多行文本C++的左上角显示复选框
- 如何将所选行的第一列值绑定到变量并在 QT 的 SQL 命令中使用它?
- 嵌入式串行读取操作和桌面PC之间可能有什么区别
- 数组之间的特征行交叉积
- 我的编译行和我的生成文件之间的区别可能导致错误
- 运行时计时函数和命令行时间之间的差异
- 如何在树模型中维护父 QStandardItems 和数据库行 ID 之间的链接
- 用c++计算多行注释之间的所有行数
- 删除每行括号之间的部分(如果存在)