编译器选择哪个函数版本

对于函数重载,函数模板和函数模板重载,C++需要一个定义良好的策略,主要以以下步骤运行

第一步:创建候选函数列表。其中包含与被调用函数的名称相同的函数和模板函数。

第二步:使用候选函数列表创建可行函数列表。这些都是参数数目正确的函数,为此有一个临时转换序列,其中包括实参类型和相应的形参类型完全匹配的情况。

第三步:确定是否有最佳的可行函数,如果有则使用它,否则该函数调用出错。

如下面调用:

void may(int);                 //#1
float may(float,float=3);          //#2 
void may(char);                //#3
char* may(char *);              //#4
char may(const char &);           //#5
template<class T>void may(const T&);   //#6
template<class T>void may(T*);       //#7
may('B');

只考虑特征标,不考虑返回类型,则#4和#7不可行。剩下5个可行的函数,从最佳到最差的顺序如下所述。

1 完全匹配,但常规由于模板。

2 提升转换,(例如,int和shorts自动转换为int,float自动转换为double)。

3 标准转换  (例如,int 转换为char,long自动转换为double)。

4.用户自定义的转换,如类声明中定义的转换。

其中#3,#5,#6都是完全匹配,但是#6为模板,故剩余#3,#5进行选择,这需要更深入的探讨。

完全匹配和最佳匹配

struct blot {int a;char b[10];};
blot int = {25,"spots"};
/* `````` */
recycle(ink);
void recycle(blot);
void recycle(const blot);
void recycle(blot&);
void recycle(const blot&);

上面原型都是完全匹配的,如果有多个匹配原型,则会生错误消息,可能是二义性这样的报错。

然而,有的时候,即使两个函数都是完全匹配,仍可完成重载解析。

指向非const的指针和引用优先于非const的指针和引用。

如果完全匹配的两个函数都是模板函数,则较具具体的模板函数优先,即编译器执行的转换最少。

template <class Type> void recycle (Type t);    //#1
template <class Type> void recycle (Type *t);    //#2

blot ink={25,"spots"};
recycle(&ink);

recycle(&ink)与#1模板匹配,Type被解释为blot*,与#2匹配被解释为blot。

recycle<blot*>(blot*)被认为是更具体的。因为在#2中,Type已经被具体化为指针。

struct debts
{
    char name[50];
    double amount;
};
template<typename T>
void showarray(T arr[], int n)
{
    cout << "template a:"<<endl;
    for (int i = 0; i < n; i++)
    {
        cout << arr[i] << ' ';
    }
    cout << endl;
}

template<typename T>
void showarray(T *arr[], int n)
{
    cout << "template b:" << endl;
    for (int i = 0; i < n; i++)
    {
        cout << *arr[i] << ' ';
    }
    cout << endl;
}
int main()
{    
    int things[6] = { 13,31,103,301,310,130 };
    struct debts mr_E[3] =
    {
        {"Ima Wolfe",2400.0},
        {"Ura Foxe",3889.2},
        {"Iby stout",231.3}
    };
    double* pd[3];
    for (int i = 0; i < 3; i++)
    {
        pd[i] = &mr_E[i].amount;
    }
    showarray(things, 6);
    cout << "mr_E's debts:" << endl;
    showarray(pd, 3);    
}

结果:

template a:
13 31 103 301 310 130
mr_E's debts:
template b:
2400 3889.2 231.3

 

 

posted @ 2022-02-11 13:11  追风&~少年  阅读(101)  评论(0)    收藏  举报