c++ - C++11 中引入了哪些重大变化?

标签 c++ c++11

我知道 C++11 中至少有一个变化会导致一些旧代码停止编译:在标准库中引入 explicit operator bool(),替换旧实例运算符 void*()。诚然,这将破坏的代码可能是一开始就不应该有效的代码,但它仍然是一个重大变化:过去有效的程序不再有效。

还有其他重大变化吗?

最佳答案

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 .

New keywords: alignas, alignof, char16_t, char32_t, constexpr, decltype, noexcept, nullptr, static_assert, and thread_local


Certain integer literals larger than can be represented by long could change from an unsigned integer type to signed long long.


Valid C++ 2003 code that uses integer division rounds the result toward 0 or toward negative infinity, whereas C++0x always rounds the result toward 0.

(不可否认,对于大多数人来说,这并不是真正的兼容性问题)。


Valid C++ 2003 code that uses the keyword auto as a storage class specifier may be invalid in C++0x.


Narrowing conversions cause incompatibilities with C++03. For example, the following code is valid in C++ 2003 but invalid in this International Standard because double to int is a narrowing conversion:

int x[] = { 2.0 };

Implicitly-declared special member functions are defined as deleted when the implicit definition would have been ill-formed.

A valid C++ 2003 program that uses one of these special member functions in a context where the definition is not required (e.g., in an expresion that is not potentially evaluated) becomes ill-formed.

我的例子:

struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }

这种 sizeof 技巧已经被一些 SFINAE 使用,现在需要改变:)


User-declared destructors have an implicit exception specification.

我的例子:

struct A {
  ~A() { throw "foo"; }
};

int main() { try { A a; } catch(...) { } }

此代码调用 terminate在 C++0x 中,但在 C++03 中没有。因为 A::~A 的隐式异常规范在 C++0x 中是 noexcept(true) .


A valid C++ 2003 declaration containing export is ill-formed in C++0x.


A valid C++ 2003 expression containing > followed immediately by another > may now be treated as closing two templates.

在 C++03 中,>>将始终是移位运算符标记。


Allow dependent calls of functions with internal linkage.

我的例子:

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)没有被采纳,因为它没有外部链接。


库变化

Valid C++ 2003 code that uses any identifiers added to the C++ standard library of C++0x may fail to compile or produce different results in This International Standard.


Valid C++ 2003 code that #includes headers with names of new C++0x standard library headers may be invalid in this International Standard.


Valid C++ 2003 code that has been compiled expecting swap to be in <algorithm> may have to instead include <utility>


The global namespace posix is now reserved for standardization.


Valid C++ 2003 code that defines override, final, carries_dependency, or noreturn as macros is invalid in C++0x.

关于c++ - C++11 中引入了哪些重大变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14194459/

相关文章:

c++ - 表达式 'i < 0' 始终为假

c++ - 测量 CUDA 分配时间

c++ - 限制变量范围的优缺点

c++ - C++11 模板中的默认位置参数

c++ - 如何使用模板在 C++ 中使用 `using` 创建别名(创建参数化别名)?

c++ - 为什么我的 vector 下标超出范围?

c++ - 如何按标题自动对方法进行排序?

c++ - 维护ABI : adding constructor to struct

c++ - 在没有赋值的情况下调用 std::move() 时会发生什么

c++ - 带有 std::vector 和带有缩减的标量变量的 OpenMP for 循环