C++ - 类型转换和二义性

类型转换:

   // 类型转换测试
    class SmallInt {
        friend SmallInt operator+(const SmallInt &lhs, const SmallInt &rhs);

    public:
        SmallInt(int i = 0) : val(i) {}

        explicit operator bool() { return bool(val); }

        operator int() const { return val; }

        operator const int() { return val; }

    private:
        int val;
    };

    SmallInt operator+(const SmallInt &lhs, const SmallInt &rhs) {
        return SmallInt(int(lhs) + int(rhs));
    }

测试代码:

   void TypeConvertTest() {
        SmallInt si1;
        si1 = 4; // 4先转换为SmallInt(4),再执行赋值操作
        si1 = 5.1; // 隐式的用户定位类型转换可以置于一个标准(内置)类型转换之前或者之后, 5.1 -> 5
//        auto sum = si1 + 3; // si1转换为int值4,再执行4 + 3,在定义operator+(const SmallInt& lhs, const SmallInt& rhs)后存在二义性
//        sum = si1 + 4.13; // 4.13 -> 4,在定义operator+(const SmallInt& lhs, const SmallInt& rhs)后存在二义性
        if (si1) {
            // 向bool的转换通常用在条件部分,因此一般定位为expicit,在条件部分会自动执行隐式转换
            cout << "this is true" << endl;
        }

        int i = si1;  // operator const int()
        const int ci = si1; // operator const int()

        return;
    }

二义性实例:

   // 类型转换二义性测试
    class B;

    class A {
    public:
        A() = default;

        A(const B &b) {} // 通过B构造A
    };

    class B {
    public:
        B() = default;

        operator A() { return A(); };  // B可以隐式准换为A
    };

    A fun1(const A &) { return A(); }

    class C {
    public:
        C(int i = 0) {};

        C(double d) {};

        operator int() { return 0; }

        operator double() { return 0.0; }
    };

    void fun2(long double) {}

    class LongDouble {
    public:
        LongDouble(double  = 0.0) {}

        operator double() { return 0.0; }

        operator float() { return 0.0f; }
    };

    void calc(int) {}

    void calc(LongDouble) {}

测试代码:

​
   void AmbiguousConvertTest() {
        LongDouble ldObj;
//        int ex1 = ldObj;  // 二义性
        float ex2 = ldObj; // OK,确定为float转换
        double dval;
        calc(dval);  // 调用calc(int),而不是calc(LongDouble),为啥???

        // 实参匹配和相同的类型转换
        B b;
        A a = fun1(b);  // 没有出现二义性??? 调用了B类的转换符

        // 转换目标为内置类型的多重类型转换
        C c1;
//        fun2(c1);  //  二义性错误,无法确定调用哪个转换函数
        fun2(static_cast<int>(c1));
        fun2(static_cast<double >(c1));
        long lg = 0;
//        C c2(lg); // 二义性错误,无法确定调用哪个构造函数
        C c2(int(lg));
        C c3(double(lg));
        
        return;
    }

​

参考: C++ Primer 第五版 第14章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值