- C++11 FAQ 中文版 - C++11 FAQ
- Stroustrup 先生关于中文版的授权许可邮件
- Stroustrup 先生关于 C++11 FAQ 的一些说明
- 关于 C++11 的一般性的问题
- 您是如何看待 C++11 的?
- 什么时候 C++0x 会成为一部正式的标准呢?
- 编译器何时将会实现 C++11 标准呢?
- 我们何时可以用到新的标准库文件?
- C++0x 将提供何种新的语言特性呢?
- C++11 会提供哪些新的标准库文件呢?
- C++0x 努力要达到的目标有哪些?
- 指导标准委员会的具体设计目标是什么?
- 在哪里可以找到标准委员会的报告?
- 从哪里可以获得有关 C++11 的学术性和技术性的参考资料?
- 还有哪些地方我可以读到关于 C++0x 的资料?
- 有关于 C++11 的视频吗?
- C++0x 难学吗?
- 标准委员会是如何运行的?
- 谁在标准委员会里?
- 实现者应以什么顺序提供 C++11 特性?
- 将会是 C++1x 吗?
- 标准中的"concepts"怎么了?
- 有你不喜欢的 C++特性吗?
- 关于独立的语言特性的问题
- __cplusplus 宏
- alignment(对齐方式)
- 属性(Attributes)
- atomic_operations
- auto – 从初始化中推断数据类型
- C99 功能特性
- 枚举类——具有类域和强类型的枚举
- carries_dependency
- 复制和重新抛出异常
- 常量表达式(constexpr)
- decltype – 推断表达式的数据类型
- 控制默认函数——默认或者禁用
- 控制默认函数——移动(move) 或者复制(copy)
- 委托构造函数(Delegating constructors)
- 并发性动态初始化和析构
- noexcept – 阻止异常的传播与扩散
- 显式转换操作符
- 扩展整型
- 外部模板声明
- 序列 for 循环语句
- 返回值类型后置语法
- 类成员的内部初始化
- 继承的构造函数
- 初始化列表
- 内联命名空间
- Lambda 表达式
- 用作模板参数的局部类型
- long long(长长整数类型)
- 内存模型
- 预防窄转换
- nullptr——空指针标识
- 对重载(override) 的控制: override
- 对重载(override) 的控制:final
- POD
- 原生字符串标识
- 右角括号
- 右值引用
- Simple SFINAE rule
- 静态(编译期)断言 — static_assert
- 模板别名(正式的名称为"template typedef")
- 线程本地化存储 (thread_local)
- unicode 字符
- 统一初始化的语法和语义
- (广义的)联合体
- 用户定义数据标识(User-defined literals)
- 可变参数模板(Variadic Templates)
- 关于标准库的问题
- abandoning_a_process
- 算法方面的改进
- array
- async()
- atomic_operations
- 条件变量(Condition variables)
- 标准库中容器方面的改进
- std::function 和 std::bind
- std::forward_list
- std::future 和 std::promise
- 垃圾回收(应用程序二进制接口)
- 无序容器(unordered containers)
- 锁(locks)
- metaprogramming(元编程)and type traits
- 互斥
- 随机数的产生
- 正则表达式(regular expressions)
- 具有作用域的内存分配器
- 共享资源的智能指针——shared_ptr
- smart pointers
- 线程(thread)
- 时间工具程序
- 标准库中的元组(std::tuple)
- unique_ptr
- weak_ptr
- system error
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
显式转换操作符
C++98 标准提供隐式和显式两种构造函数,也就是说,声明为显式形式的构造函数所定义的转换只能用于显式转换,而其他形式的构造函数则用于隐式转换。例如:
struct S { S(int); }; // “普通构造函数”默认是隐式转换
S s1(1); // ok, 直接构造
S s2 = 1; // ok, 隐式拷贝构造
void f(S);
// 能通过编译(但是经常会产生意外结果——如果 S 是 vector 类型会怎么样呢?)
// 译注:详见下一用例的解释
f(1);
struct E { explicit E(int); }; // 显式构造函数
E e1(1); // ok
E e2 = 1; // 错误(但是常常会让人感到意外——这怎么会错呢?)
void f(E);
// 该处会产生编译错误(而非编译通过),以避免因隐式类型转换而得到莫名其妙的结果。
// 例如 std::vector::vector(int size), 该构造函数在标准库中定义为显式类型转换,
// (译注:以避免程序员为了初始化一个只含有一个元素 10 的数组而写出如下代码:
// vector<int> vec = 10;
// 而实际上该代码的含义却是定义一个初始包含 10 个元素的数组)
f(1);
然而,禁止从构造函数作隐式转换(以避免问题),并没有堵住全部漏洞。如果某个类本身禁止改动,那么可以从另一个不同的类中定义一个转换操作符。例如:
struct S { S(int) { } /* … */ };
struct SS {>
int m;
SS(int x) :m(x) { }
// 在 struct S 无须定义 S(SS)——所谓的“非侵入”式做法
operator S() { return S(m); }
};
SS ss(1); // ok; 默认构造函数
S s1 = ss; // ok; 隐式转换为 S 后调用拷贝构造函数
S s2(ss); // ok; 隐式转换为 S 后调用直接构造函数
void f(S);
f(ss); // ok; 隐式转换为 S 后传参
(译注:这段代码的意义,实际是通过 SS 作为中间桥梁,将 int 转换为 S。)
遗憾的是,C++98 中无法定义”显式转换操作符”来完全禁止某个类相关的隐式转换(因为除此之外鲜有用武之地)。C++11 则高瞻远瞩,添加了这个特性。例如:
struct S { S(int) { } };
struct SS {
int m;
SS(int x) :m(x) { }
// 因为结构体 S 中没有定义构造函数 S(SS)
// 无法将 SS 转换为 S,所以只好在 SS 中定义一个返回 S 的转换操作符,
// 将自己转换为 S。
// 转换动作,可以由目标类型 S 提供,也可以由源类型 SS 提供。)
explicit operator S() { return S(m); }
};
SS ss(1); // ok; 默认构造函数
S s1 = ss; // 错误; 拷贝构造函数不能使用显式转换
S s2(ss); // ok; 直接构造函数可以使用显式转换
void f(S);
f(ss); // 错误; 从 SS 向 S 的转换必须是显式的.
// 译注: 强制类型转换也可使用显式转换,例如
// S s3 = static_cast<S>(ss);
参考:
- Standard: 12.3 Conversions
- [N2333=07-0193] Lois Goldthwaite, Michael Wong, and Jens Maurer:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论