C++11 引入了哪些重大变化?
我知道C++11中至少有一个变化会导致一些旧代码停止编译:在标准库中引入explicit operator bool()
,替换旧实例operator void*()
.诚然,这将破坏的代码可能是一开始就不应该有效的代码,但它仍然是一个破坏性的变化:曾经有效的程序不再有效.
还有其他重大变化吗?
解决方案FDIS 在附录 C.2
C++ 和 ISO C++ 2003"中有一个不兼容部分.
总结,在此处解释 FDIS,使其(更好)适合作为 SO 答案.我添加了一些我自己的例子来说明差异.
有一些与库相关的不兼容问题,我不完全知道其中的含义,因此我将这些问题留给其他人详细说明.
核心语言
<小时>#define u8 "abc"const char *s = u8"def";//以前是abcdef",现在是def"
<小时>
#define _x "那里""hello"_x//现在是用户定义的字符串文字.以前,扩展 _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();};结构 B : A { };int main() { sizeof B();/* 在 C++03 中有效,在 C++0x 中无效 */}
一些SFINAE已经使用了这种sizeof技巧,现在需要更改:)
<小时><块引用>用户声明的析构函数具有隐式异常规范.
我的例子:
struct A {~A() { 抛出foo";}};int main() { 尝试 { A a;} 抓住(...) { } }
此代码在 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) { }模板void g(T t) { f(t);}int main() { g(0);}
在 C++03 中,它调用 f(long)
,但在 C++0x 中,它调用 f(int)
.需要注意的是,在C++03和C++0x中,以下调用f(B)
(实例化上下文仍然只考虑extern链接声明).
struct B { };结构 A : B { };模板void g(T t) { f(t);}静态无效 f(A) { }无效 f(B) { }int main() { A a;克(一);}
更好的匹配f(A)
没有取,因为它没有外部链接.
库变化
<块引用>使用添加到 C++ 标准的任何标识符的有效 C++ 2003 代码C++0x 库可能无法编译或在本国际标准中产生不同的结果.
<小时><块引用>
#includes
标头和新 C++0x 标准库标头名称的有效 C++ 2003 代码在本国际标准中可能无效.
<小时><块引用>
已编译预期交换位于 中的有效 C++ 2003 代码可能必须改为包含
<小时><块引用>
全局命名空间 posix
现在保留用于标准化.
<小时><块引用>
将 override
、final
、carries_dependency
或 noreturn
定义为宏的有效 C++ 2003 代码在C++0x.
I know that at least one of the changes in C++11 that will cause some old code to stop compiling: the introduction of explicit operator bool()
in the standard library, replacing old instances of operator void*()
. Granted, the code that this will break is probably code that should not have been valid in the first place, but it's still a breaking change nonetheless: programs that used to be valid no longer are.
Are there any other breaking changes?
解决方案The FDIS has a section for incompatibilities, at appendix C.2
"C++ and ISO C++ 2003".
Summary, paraphrasing the FDIS here, to make it (better) suitable as a SO answer. I added some examples of my own to illustrate the differences.
There are a few library-related incompatibilities where I don't exactly know the implications of, so I leave those for others to elaborate on.
Core language
#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.
(admittedly not really a compatibility problem for most people).
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 de?ned 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.
Example by me:
struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }
Such sizeof tricks have been used by some SFINAE, and needs to be changed now :)
User-declared destructors have an implicit exception specification.
Example by me:
struct A {
~A() { throw "foo"; }
};
int main() { try { A a; } catch(...) { } }
This code calls terminate
in C++0x, but does not in C++03. Because the implicit exception specification of A::~A
in C++0x is 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.
In C++03, >>
would always be the shift-operator token.
Allow dependent calls of functions with internal linkage.
Example by me:
static void f(int) { }
void f(long) { }
template<typename T>
void g(T t) { f(t); }
int main() { g(0); }
In C++03, this calls f(long)
, but in C++0x, this calls f(int)
. It should be noted that in both C++03 and C++0x, the following calls f(B)
(the instantiation context still only considers extern linkage declarations).
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); }
The better matching f(A)
is not taken, because it does not have external linkage.
Library changes
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
, ornoreturn
as macros is invalid in C++0x.
相关文章