重载函数的模糊性:如何解决?

时间:2016-10-12 09:45:47

标签: c++ operator-overloading ambiguity

我已经重载<<以两种不同的形式打印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;
}

1 个答案:

答案 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

的所有参数      
      
  1. F1 至少有一个参数,其隐式转换优于该参数的相应隐式转换    F2
  2.   
  3. 或。如果不是这样,(仅在通过转换进行非类初始化的上下文中),标准转换序列来自返回类型    F1 到正在初始化的类型要好于返回类型 F2
  4. 的标准转换序列   
  5. 或者,如果没有, F1 是非模板功能,而 F2 是模板专业化
  6.   
  7. 或者,如果没有, F1 F2 都是模板专精, F1 根据部分排序规则更专业   用于模板专业化
  8.