主要观点:
- 讨论了 C++中“不良格式但无需诊断(IFNDR)”的概念,常见的意外来源是违反“单一定义规则(ODR)”,通过基于编译时开关定义不同的类或函数。
- 以
Widget类为例,若不同的.cpp文件根据编译时开关有不同的定义,链接时会违反 ODR。 - 类型别名不受 ODR 限制,可在不同翻译单元中有不同定义。
- 通过模板
WidgetT实现了不同调试版本和非调试版本的Widget,并通过外部模板声明和别名来选择使用。 - 模板的实现不在头文件中,需要显式实例化模板以触发代码生成。
- 当客户端使用
widget.h头文件时,可根据调试设置选择不同的Widget版本,但不同版本之间的交互可能导致链接错误,如在类中使用Widget或在全局函数中返回Widget时。
关键信息:
Widget类中根据编译时开关有不同的Log方法定义。WidgetT模板有调试和非调试版本,分别有Logger或std::monostate成员。- 需显式实例化
WidgetT模板。 - 客户端使用的
Widget别名不同可能导致链接错误,类或全局函数中使用Widget也可能引发 ODR 违规。
重要细节:
[msvc::no_unique_address]属性用于告知编译器可将空对象折叠为无,在非调试时消失。- 若一个客户端暴露的类使用
Widget,不同调试设置的客户端可能对该类中Widget的版本有不同理解,引发 ODR 违规。 - 提到类似技术可用于处理
wchar_t的多种可能定义,并给出相关阅读链接。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。