c++11的类型转换函数

一、类型转换

类型转换,在任何语言中都存在这个现实的问题。比如把一个两个字节的数字转成四个字节的,把浮点的转成单精度的等等。一般来说,从精度低,长度短(指占有的内存空间)向高精度大空间的类型转换时,不会存在什么问题,但是反过来事情就多了。特别是在面向对象编程时,类型的转换不只有基本类型还有数据封装类型,这样在转换时就提出了更复杂的问题。
在早期的c++的转换中,无论哪种类型的转换,基本上都是强制转换,后来增加了类似于static_cast之类的转换方式,但总体上用来还是感觉不是很舒适。但一时半会儿确实又无法提出更好的解决方法,不过还是说过的话,做不到最好不代表没有动作,所以在c++的新标准中提供了一些优化的方法。

二、c++11提供的方式

在c++的新标准中提供了operator类型转换,这个和原来的重载是一样的标识符。它的定义如下:

operator 转换类型标识	(1)	
explicit operator 转换类型标识	(2)	                (C++11 起)
explicit ( 表达式 ) operator 转换类型标识	(3)	(C++20 起)

但是,在这种场景下使用使用这个关键字是有要求:
1、使用operator不能返回值
2、不能拥有参数
3、不能出现数组和函数符号即[]和()两种符号(因此转换到诸如数组的指针的类型要求使用类型别名、typedef 或标识模板:见下文)。无论是否使用 typedef,转换类型标识都不能代表数组或函数类型。

看一下具体的例子就明白了:

struct X {
    // 隐式转换
    operator int() const { return 7; }
 
    // 显式转换
    explicit operator int*() const { return nullptr; }
 
//   错误:转换类型标识中不允许出现数组运算符
//   operator int(*)[3]() const { return nullptr; }
    using arr_t = int[3];
    operator arr_t*() const { return nullptr; } // 可以通过 typedef 转换
//  operator arr_t () const; // 错误:不允许在任何情况下转换到数组
};
 
int main()
{
    X x;
 
    int n = static_cast<int>(x);   // OK:设 n 为 7
    int m = x;                     // OK:设 m 为 7
 
    int* p = static_cast<int*>(x);  // OK:设 p 为空
//  int* q = x; // 错误:没有隐式转换
 
    int (*pa)[3] = x;  // OK
}

这个东西要和转换构造函数区别:

struct To {
    To() = default;
    To(const struct From&) {} // 转换构造函数
};
 
struct From {
    operator To() const {return To();} // 转换函数
};
 
int main()
{
    From f;
    To t1(f); // 直接初始化:调用构造函数
// (注意,如果转换构造函数不可用,那么会选择隐式的复制构造函数,且调用转换函数以准备其参数)
    To t2 = f; // 复制初始化:有歧义
// (注意,如果转换函数来自非 const 类型,例如 From::operator To(); 
//  那么它在这种情况下会替代构造函数被选中)
    To t3 = static_cast<To>(f); // 直接初始化:调用构造函数
    const To& r = f; // 引用初始化:有歧义
}

“用户定义的转换函数在隐式转换的第二阶段被调用,第二阶段由零或一个转换构造函数或零或一个用户定义转换函数构成。如果转换函数和转换构造函数都能用于进行某个用户定义转换,那么复制初始化和引用初始化语境中的重载决议同时考虑转换函数和转换构造函数,但在直接初始化语境中只考虑转换构造函数”。这是文档上的说明,对照着上面的例程,就很清楚的看明白了。

另外目前支持的拖尾类型函数auto在此处不支持:


转换类型标识 中可以使用占位符 auto,以指定一个推导的返回类型:

struct X {
    operator int(); // OK
    operator auto() -> short;  // 错误:尾随返回类型不是此类语法的一部分
    operator auto() const { return 10; } // OK:推导的返回类型
};

c++的麻烦就在于此,只要不怕麻烦就不怕c++。

三、总结

c++的文档是越来越复杂,所以学习成本在增加,虽然学习的曲线有些减缓,但未必能起到关键的作用。c++标准的大佬们儿还要努力。其实看c++ 这么多的技术点,目的其实就是为了更灵活,而越是灵活,对新手和菜鸟来说,它就是一场灾难。所以对c++的学习者来说,踏实的把基础搞好,厚积薄发,才是正道。可现在这个社会,谁肯呢?
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值