在C ++ 11中引入了什么突变? [英] What breaking changes are introduced in C++11?
问题描述
我知道C ++ 11中的至少一个更改会导致一些旧代码停止编译:在中显式运算符bool()
的引入标准库,替换 operator void *()
的旧实例。授予,这将破坏的代码可能是应该不是有效的代码,但它仍然是一个突变:过去有效的程序不再是。
有没有其他破坏性更改?
FDIS有一个不兼容部分, $ c> C.2 C ++和ISO C ++ 2003。
摘要,在这里解释FDIS,作为答案。我添加了一些自己的例子来说明差异。
有一些与库相关的不兼容性,我不完全知道它的含义,所以我留给别人详细说明。
核心语言
#define u8abc
const char * s = u8def; //以前的abcdef,现在为def
#define _xthere
hello_x //现在是用户定义的字符串文字。以前,扩展_x。
alignas,alignof,char16_t,char32_t,constexpr,decltype,noexcept,nullptr,static_assert和thread_local
大于可以由long表示的某些整数文字可以从无符号整数类型更改为signed long long。
b b b b b 有效的C ++ 2003代码使用整数除法将结果向0或负无穷大舍入,而C ++ 0x总是舍入结果为0。
(绝对不是大多数人的兼容性问题)。
使用关键字
auto
作为存储类说明符的有效C ++ 2003代码在C ++ 0x中无效。
转换会导致与C ++ 03不兼容。例如,以下代码在C ++ 2003中有效,但在本标准中无效,因为double to int是缩小的转换:
int x [] = {2.0};
隐含声明
有效的C ++ 2003程序在上下文中使用这些特殊成员函数之一,
我的例子:
/ p> struct A {private:A(); };
struct B:A {};
int main(){sizeof B(); / *在C ++ 03中有效,在C ++ 0x中无效* /}
已被某些SFINAE使用,现在需要更改:
我的例子:
struct A {
〜A(){throwfoo; }
};
int main(){try {A a; } catch(...){}}
此代码调用 / code>在C ++ 0x,但不是在C ++ 03。因为C ++ 0x中
A ::〜A
的隐式异常规范是 noexcept(true)
。
一个有效的C ++ 2003声明,包含
export
在C ++ 0x中是不成形的。
一个有效的C ++ 2003表达式,包含
>
后面紧跟另一个>
现在可以视为关闭两个模板。
< blockquote>
在C ++ 03中,
>>
始终是移位运算符令牌。
允许具有内部链接的函数的相关调用。
我的示例:
static void f }
void f(long){}
template< typename T>
void g(T t){f(t); }
int main(){g(0); }在C ++ 03中,这会调用f(long) code>,但在C ++ 0x中,这会调用
f(int)
。应该注意,在C ++ 03和C ++ 0x中,以下调用f(B)
(实例化上下文仍然只考虑extern链接声明) / p>
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 ++ 2003代码使用添加到C ++标准
库C ++ 0x的任何标识符可能无法在本国际标准中编译或产生不同的结果。
有效的C ++ 2003程式码
#includes
标题的新C ++ 0x标准库标题的名称在此国际标准中可能无效。
已编译的有效C ++ 2003代码期望交换位于
< algorithm>
可能必须改为包含< utility>
全局命名空间
posix
现在保留用于标准化。
有效的C ++ 2003代码定义
override
final
,carriers_dependency
或noreturn
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 ofoperator 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 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.
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 ofA::~A
in C++0x isnoexcept(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 callsf(int)
. It should be noted that in both C++03 and C++0x, the following callsf(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.
这篇关于在C ++ 11中引入了什么突变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!