FDIS 在附录 C.2“C++ 和 ISO C++ 2003”中有一个关于不兼容性的部分。
总结,在这里解释 FDIS,使其(更好)适合作为 SO 答案。我添加了一些我自己的例子来说明差异。
有一些与库相关的不兼容问题我并不完全了解其含义,因此我将其留给其他人详细说明。
核心语言
#define u8 "abc"
const char *s = u8"def"; // Previously "abcdef", now "def"
#define _x "there"
"hello"_x // now a user-defined-string-literal. Previously, expanded _x .
新关键字:alignas、alignof、char16_t、char32_t、constexpr、decltype、noexcept、nullptr、static_assert 和 thread_local
某些大于 long 可以表示的整数文字可以从无符号整数类型更改为有符号 long long。
使用整数除法的有效 C++ 2003 代码将结果向 0 或负无穷大四舍五入,而 C++0x 始终将结果向 0 四舍五入。
(诚然,对于大多数人来说,这并不是真正的兼容性问题)。
使用关键字auto 作为存储类说明符的有效 C++ 2003 代码在 C++0x 中可能无效。
缩小转换范围会导致与 C++03 不兼容。例如,以下代码在 C++ 2003 中有效,但在本国际标准中无效,因为 double 到 int 是一种缩小转换:
int x[] = { 2.0 };
当隐式定义格式错误时,隐式声明的特殊成员函数被定义为删除。
在不需要定义的上下文中使用这些特殊成员函数之一的有效 C++ 2003 程序(例如,在可能不会被评估的表达式中)变得不正确。
我的例子:
struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }
一些 SFINAE 已经使用了这种 sizeof 技巧,现在需要更改 :)
用户声明的析构函数有一个隐式的异常规范。
我的例子:
struct A {
~A() { throw "foo"; }
};
int main() { try { A a; } catch(...) { } }
此代码在 C++0x 中调用 terminate,但在 C++03 中不调用。因为 C++0x 中A::~A 的隐式异常规范是noexcept(true)。
包含export 的有效C++ 2003 声明在C++0x 中格式不正确。
现在可以将包含> 后跟另一个> 的有效C++ 2003 表达式视为关闭两个模板。
在 C++03 中,>> 始终是移位运算符标记。
允许对具有内部链接的函数进行依赖调用。
我的例子:
static void f(int) { }
void f(long) { }
template<typename T>
void g(T t) { f(t); }
int main() { g(0); }
在 C++03 中,此调用 f(long),但在 C++0x 中,此调用 f(int)。需要注意的是,在 C++03 和 C++0x 中,以下调用 f(B)(实例化上下文仍然只考虑外部链接声明)。
struct B { };
struct A : B { };
template<typename T>
void g(T t) { f(t); }
static void f(A) { }
void f(B) { }
int main() { A a; g(a); }
没有采用更好匹配的f(A),因为它没有外部链接。
库更改
使用添加到 C++ 标准的任何标识符的有效 C++ 2003 代码
C++0x 库可能无法编译或在本国际标准中产生不同的结果。
#includes 标头名称为新 C++0x 标准库标头的有效 C++ 2003 代码在本国际标准中可能无效。
已编译的有效 C++ 2003 代码预期交换位于 <algorithm> 中可能必须改为包含 <utility>
全局命名空间 posix 现在保留用于标准化。
将 override、final、carries_dependency 或 noreturn 定义为宏的有效 C++ 2003 代码在 C++0x 中无效。