我已经重载<<
以两种不同的形式打印pair
的内容(请参阅下面的代码)。第一种形式特定于定义的pair
类型。对于任何一对,第二个是template
d。这两个中的任何一个都适合我的配对类型。当两个原型都在main
的定义之前时,使用第一个(特定的)原型,而不管原型的顺序如何。只有当第一个原型被评论时,才会使用第二个原型。
为什么以这种方式解决模糊性,决定使用哪个适当的函数?
#include <iostream>
#include <map>
using namespace std;
typedef pair<string, char> pair_t;
ostream& operator<<(ostream& os, const pair_t& p); // First form, specific
template<class first_class, class second_class>
ostream& operator<<(ostream& os, const pair<first_class, second_class>& p); // Second form, generic
int main(void) {
pair_t p2;
p2 = make_pair("Fer", 'C');
cout << p2 << endl;
return 0;
}
ostream& operator<<(ostream& os, const pair_t& p)
{
os << p.first << " obtained \'" << p.second << "\'";
return os;
}
template<class first_class, class second_class>
ostream& operator<<(ostream& os, const pair<first_class, second_class>& p)
{
os << "(" << p.first << ", " << p.second << ")";
return os;
}
答案 0 :(得分:2)
std::pair
有一个重载转换constructor,即:
template< class U1, class U2 >
constexpr pair( const pair<U1, U2>& p );
你这样做了:
p2 = make_pair("Fer", 'C');
调用std::make_pair("Fer", 'C')
会返回std::pair<const char[4], char>
类型的对象,该对象可转换为std::pair<std::string, char>
。
将其传递给std::cout
,需要重载解析来实例化重载的函数模板,从而创建一组函数特化:
ostream& operator<<(ostream& os, const std::pair<std::string, char>& p)
ostream& operator<<(ostream& os, const std::pair<std::string, char>& p); //compiler generated template specialization
可以选择一个可以选择的规则here
对于每对可行函数F1和F2,隐式转换 从第i个参数到第i个参数的序列被排序为 确定哪一个更好(除了第一个参数,隐含的 静态成员函数的object参数对该函数没有影响 排名)
F1 被确定为比 F2 更好的功能,如果 F1 的所有参数的隐式转换不比隐含的更差 转换 F2 ,和
的所有参数
- F1 至少有一个参数,其隐式转换优于该参数的相应隐式转换 F2
- 或。如果不是这样,(仅在通过转换进行非类初始化的上下文中),标准转换序列来自返回类型 F1 到正在初始化的类型要好于返回类型 F2
的标准转换序列- 或者,如果没有, F1 是非模板功能,而 F2 是模板专业化
- 或者,如果没有, F1 和 F2 都是模板专精, F1 根据部分排序规则更专业 用于模板专业化
醇>