使用模板参数模板解决模棱两可调用的 C++ 默认行为是啥?
Posted
技术标签:
【中文标题】使用模板参数模板解决模棱两可调用的 C++ 默认行为是啥?【英文标题】:What is c++ default behavior to resolve ambiguous calls with template of template parameter?使用模板参数模板解决模棱两可调用的 C++ 默认行为是什么? 【发布时间】:2016-11-08 18:12:50 【问题描述】:考虑以下代码:
#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>>
已用于第三次调用。
那么这种情况下的默认行为是什么?我的理论是,它采用在这种情况下有意义的最严格的例子。 这是真的?这是在某处指定的,因为我不能相信随机性。
这里的向量类没有什么特别之处。我实际上是在实现一些图算法,但是由于我可能对图有不同的表示形式,例如作为邻接表向量 >> 或作为弧表向量 > ,以及弧的不同表示取决于它是否是未加权/加权图/流网络,它可能携带不同类型的信息。我正在尝试使用模板编写通用代码,但目前我正面临这种问题。
谢谢
【问题讨论】:
重载解决的逻辑并不总是显而易见的。有很多细节。见more on the subject。 【参考方案1】:您的第二个 f
据说比您的第一个 f
更专业,因此当两者都匹配时,第二个 f
将赢得重载决议。
更专业的确切定义在标准中详细给出,但基本思想是弄清楚对一个的任何调用是否总是可以被另一个匹配(但不是副-反之亦然)。也就是说,如果您有第二个f
的std::vector<X>&
,您知道它也可以匹配第一个f
的T&
。但是,如果第一个 f
有一个通用的 X&
,则不能保证它会匹配第二个 f
的 std::vector<T>&
。
【讨论】:
以上是关于使用模板参数模板解决模棱两可调用的 C++ 默认行为是啥?的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 中使用默认参数跳过模板参数真的不可能吗,为啥语法建议不这样?