首页 > 代码库 > 【足迹C++primer】50、避免含糊转换

【足迹C++primer】50、避免含糊转换

避免含糊转换

参数匹配和相互转换

struct B;
struct A
{
    A()=default;
    A(const B&)    //吧B负责给A,拷贝构造函数
    {//嘿,这里我有点明白了,只要 后面调用了这个函数,那么这个函数就得有定义
        //不能只声明不定义
        cout<<"调用了A(const B&)转换!"<<endl;
    }
};


struct B
{
    operator A() const {cout<<"调用了operator A() const!"<<endl;}     //吧B转换为A
};

A f(const A&)   //这个要写在外面,因为下面a1会调用f这个函数- -,浪费我时间
{
    cout<<"调用了函数f(const A&)!"<<endl;
}

void fun1()
{
    B b;
//    A a=f(b);    错误的,原因是这里有两个转换的方式,编译器不知道调用哪个
    //如果我们非要调用不可,那么只能这样了
    A a1=f(b.operator A());     //这里用B的转换操作
    A a2=f(A(b));
}

Ambiguities and Multiple Conversions to Built-in Types

struct C
{
    C(int = 0){cout<<"调用构造函数C(int=0)"<<endl;}
    C(double) {cout<<"调用构造函数C(double)"<<endl;}

    operator int() const {cout<<"调用操作符转换operator int()"<<endl;}
    operator double() const {cout<<"调用操作符转换operator double()"<<endl;}
    //...
};

void f2(long double){cout<<"调用函数f2(long double)"<<endl;}

void fun2()
{
    C c();
//    f2(c);      //error :参数歧义
    long lg;
//    C c2(lg);   //error :参数歧义
    //再来看一个例子
    short s=42;
    C c3(s);    //调用C::C(int)完成转换,吧short转换成int比转换成double好的多,所以呵呵

}

Overloaded Functions and Converting Constructors

struct D
{
    D(int){}
};

struct E
{
    E(int){}
};

void manip(const D&) { cout<<"调用void manip(const D&)"<<endl;}
void manip(const E&) { cout<<"调用void manip(const E&)"<<endl;}

void fun3()
{
//    manip(10);  //error: call of overloaded 'manip(int)' is ambiguous,歧义了
    //我们可以这样写,直接告诉编译器要调用哪个
    manip(D(10));   //OK:调用 manip(const D&)
}

Overloaded Functions and User-Defined Conversion
重载函数和用户定义的转换

struct F
{
    F(double) {cout<<"调用F的构造函数F(double)"<<endl;}

};

void manip2(const D&) { cout<<"调用void manip2(const D&)"<<endl;}
void manip2(const F&) { cout<<"调用void manip2(const F&)"<<endl;}

void fun4()
{
//    manip2(10); 系统不知道要用哪个
    manip2(D(10));
    manip2(F(10));
}

Function Matching and Overloaded Operators

class SmallInt
{
    friend SmallInt operator+(const SmallInt& si1, const SmallInt& si2){cout<<"这里调用+处理"<<endl;}
public:
    SmallInt(int=0){cout<<"调用SmallInt(int=0)构造函数"<<endl;}
    operator int() const {return val;}
private:
    size_t val;
};

void fun5()
{
    SmallInt s1, s2;
    SmallInt s3=s1+s2;
    cout<<"??"<<endl;
//    int i=s3+0;     这里歧义,s3可以转换成int类型,也可以吧0转换成SmallInt类型,然后准话成int类型
}

the all code!!!

/**
* 功能:避免含糊转换
* 时间:2014年7月20日09:18:59
* 作者:cutter_point
*/

#include<iostream>

using namespace std;

/**
参数匹配和相互转换
*/
struct B;
struct A
{
    A()=default;
    A(const B&)    //吧B负责给A,拷贝构造函数
    {//嘿,这里我有点明白了,只要 后面调用了这个函数,那么这个函数就得有定义
        //不能只声明不定义
        cout<<"调用了A(const B&)转换!"<<endl;
    }
};


struct B
{
    operator A() const {cout<<"调用了operator A() const!"<<endl;}     //吧B转换为A
};

A f(const A&)   //这个要写在外面,因为下面a1会调用f这个函数- -,浪费我时间
{
    cout<<"调用了函数f(const A&)!"<<endl;
}

void fun1()
{
    B b;
//    A a=f(b);    错误的,原因是这里有两个转换的方式,编译器不知道调用哪个
    //如果我们非要调用不可,那么只能这样了
    A a1=f(b.operator A());     //这里用B的转换操作
    A a2=f(A(b));
}

/**
Ambiguities and Multiple Conversions to Built-in Types
*/
struct C
{
    C(int = 0){cout<<"调用构造函数C(int=0)"<<endl;}
    C(double) {cout<<"调用构造函数C(double)"<<endl;}

    operator int() const {cout<<"调用操作符转换operator int()"<<endl;}
    operator double() const {cout<<"调用操作符转换operator double()"<<endl;}
    //...
};

void f2(long double){cout<<"调用函数f2(long double)"<<endl;}

void fun2()
{
    C c();
//    f2(c);      //error :参数歧义
    long lg;
//    C c2(lg);   //error :参数歧义
    //再来看一个例子
    short s=42;
    C c3(s);    //调用C::C(int)完成转换,吧short转换成int比转换成double好的多,所以呵呵

}

/**
Overloaded Functions and Converting Constructors
*/
struct D
{
    D(int){}
};

struct E
{
    E(int){}
};

void manip(const D&) { cout<<"调用void manip(const D&)"<<endl;}
void manip(const E&) { cout<<"调用void manip(const E&)"<<endl;}

void fun3()
{
//    manip(10);  //error: call of overloaded 'manip(int)' is ambiguous,歧义了
    //我们可以这样写,直接告诉编译器要调用哪个
    manip(D(10));   //OK:调用 manip(const D&)
}

/**
Overloaded Functions and User-Defined Conversion
重载函数和用户定义的转换
*/
struct F
{
    F(double) {cout<<"调用F的构造函数F(double)"<<endl;}

};

void manip2(const D&) { cout<<"调用void manip2(const D&)"<<endl;}
void manip2(const F&) { cout<<"调用void manip2(const F&)"<<endl;}

void fun4()
{
//    manip2(10); 系统不知道要用哪个
    manip2(D(10));
    manip2(F(10));
}

/**
14.9.3. Function Matching and Overloaded Operators
*/

class SmallInt
{
    friend SmallInt operator+(const SmallInt& si1, const SmallInt& si2){cout<<"这里调用+处理"<<endl;}
public:
    SmallInt(int=0){cout<<"调用SmallInt(int=0)构造函数"<<endl;}
    operator int() const {return val;}
private:
    size_t val;
};

void fun5()
{
    SmallInt s1, s2;
    SmallInt s3=s1+s2;
    cout<<"??"<<endl;
//    int i=s3+0;     这里歧义,s3可以转换成int类型,也可以吧0转换成SmallInt类型,然后准话成int类型
}

int main()
{
    cout<<">>----------------fun1---------------------<<"<<endl;
    fun1();
    cout<<">>----------------fun2---------------------<<"<<endl;
    fun2();
    cout<<">>----------------fun3---------------------<<"<<endl;
    fun3();
    cout<<">>----------------fun4---------------------<<"<<endl;
    fun4();
    cout<<">>----------------fun5---------------------<<"<<endl;
    fun5();


    return 0;
}



大家其实应该也看到了,我这个其实是前天就做完了,今天才发上来,因为我要是一做完就发的话会嘿嘿,就不能偷懒了大笑
最近开始喜欢喝茶了,但是每次把茶叶放的多多的,好苦。。。只有冲了几次冲淡了之后那味道,越喝越甜,越喝越提神。
还有就是,坏事从来都是成双结对地来,不过根据我的经历来说,坏事过后好事似乎也是接二连三的来啊!!!大笑















【足迹C++primer】50、避免含糊转换