template函数和函数的重载的调用判断

来源:互联网 发布:javascript的var 编辑:程序博客网 时间:2024/05/22 03:08


struct H {};

struct G
{
    operator H() const { printf("!!!/n"); return H();}
};

template <class T>
void ff(T, H) //T不用转换,H 转换一次,共一次。T参数满足--当在其他同名函数中没有这个参数的满足的情况下,范型算是满足(共一次)
{
    printf("int,T/n");
}

void ff(int, G) //G不用转换,int转换一次,共一次。G参数满足(共一次)

{
    printf("int,float/n");
}


short i = 0;
G g;
ff(i, g);

编译错误。因为2个函数都需要转换一次,并且满足的参数次数一致,都一次。所以错误。

调用哪个函数的判断的标准是转换次数的大小。选择次数小的。但是在转换次数一致的情况下会去检查参数的满足次数,选择满足次数多的。(当然,这是在编译器能够推断模板参数的情况下,即可以具现模板函数的情况下)

template <class T>
void ff(T, int) //T不用转换,int转换一次
{
    printf("int,T/n");
}

void ff(short, float) //short不用转换,float转换2次
{
    printf("int,float/n");
}

 

short i = 0;
short s = 0;
ff(i, s);

 

输出int T

 

再看个例子:

void fffff(float)
{
    printf("1111/n");
}

template <class T>
void fffff(int)
{
    printf("2222/n");
}

fffff(int());

 

输出为1111, 为什么不是2222呢,不是int的转换次数小么,的确是int次数小,但是因为编译器推断不出T的类型,所以并不会具现化模板函数,这样就会走非模板的函数,即float.

 

 

此外用户定义的转换会先于系统的隐式转换。

struct Convert
{
    operator float() const {printf("float/n"); return 1.0;}
    operator int() {printf("int/n"); return 1;}
};
void ffff(float)
{
    printf("float/n");
}

ffff(Convert());

输出是int float    说明用户转换先于系统转换被调用,因为
operator float() const {printf("float/n"); return 1.0;}要先把Convert->const Convert是属于先系统调用,所以还是

选择int转换。(不过转换次数还是算一次, 即const volatile的转换不算在转换次数里