考虑以下代码:
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
void f(T& a) {
cout << "a" << endl;
}
template <typename T>
void f(vector<T>& a) {
cout << "b" << endl;
}
int main(int argc, char** argv) {
vector<vector<int>> v;
f<vector<vector<int>>>(v);
f<vector<int>>(v);
f(v);
}
在f的两个第一次调用中,我明确指定了我想要使用的模板版本,因此我可以控制要调用的函数版本。
第三个隐式调用应该是不明确的,因为我们可以选择显示两个第一个调用。令人惊讶的是,g ++编译器并没有侮辱我并且没有抱怨就完成了它的工作。
输出
a
b
b
表示f<vector<int>>
已用于第三次通话。
那么这种情况的默认行为是什么?我的理论是,在这种情况下,它需要最具限制性的实例才有意义。 这是真的?这是指定的地方,因为我不能相信随机性。
这里的矢量类没有什么特别之处。我实际上实现了一些图算法,但是因为我可能对图形有不同的表示,例如作为邻接列表向量&lt;矢量&lt;外向的&lt; weighttype&gt;&gt;&gt;或者作为弧列表向量&lt;弧&lt; weighttype&gt;&gt;以及弧的不同表示取决于它是否是未加权/加权图/流网络,它可以携带不同类型的信息。我正在尝试使用模板编写通用代码,但我现在正面临这样的问题。
谢谢
答案 0 :(得分:3)
您的第二个f
被认为比您的第一个f
更专业,因此当两个匹配时,第二个f
赢得重载解析。
更专业的的确切定义在标准中详细给出,但基本思路是弄清楚对一个人的任何一个呼叫是否总能与另一个人匹配(但不是反之亦然)。也就是说,如果第二个std::vector<X>&
有f
,您知道第一个T&
也可以匹配f
。但是,如果您对第一个X&
有一般f
,那么就不能保证第二个std::vector<T>&
匹配f
。