A.1 C++11和C++03的不兼容项目
条目1 在C++11中R、u8、u8R、u、uR、U、UR和LR是新的字符串修饰符,当用它们来修饰字符串时,即使它们是宏名,也将作为修饰符来解释。比如:
define u8 "AAAAA"
const char*s=u8 "u-eight-string";
在C++03中s是字符串“AAAAAu-eight-string”;在C++11中s是一个UTF-8的字符串,其内容是“u-eight-string”。
条目2 C++11支持用户自定义的字面常量,这会引起一些和C++03不一致的行为,比如:
define_x "world"
"hello"_x
在C++03中"hello"_x会拼接成hello world;而在C++11中"hello"_x会作为一个用户自定义字面常量来使用,例如:
std::string operator""_x(const char*s){
return std::string(s);
}
那么"hello"_x将会作为函数调用返回一个类型为std::string的变量,这个返回变量的内容是hello。
条目3 C++11引入了一些新的关键字,如果C++03代码用到这些标识符会被C++11视为非法的代码。这些关键字包括alignas、alignof、char16_t、char32_t、constexpr、decltype、noexcept、nullptr、static_assert和thread_local。
条目4 C++11引入了C99的新类型long long。类似C99,对于长于long类型的整型常量将会被转换成signed long long类型。而在C++03中,长于long类型的整型常量将会被转换成无符号整数,如unsigned long。例如214748364700在C++11中将会被识别为long long类型数据。
条目5 C++11和C99一样,对整数向“0”取商(/)或取余(%);而C++03允许向负无穷取商或取余。
条目6 关键字auto不再被用来作为存储类型的修饰符,而其表示修饰的类型是由初始化表达式推导而来。
条目7 C++11要求数组初始化时,不能将数据的类型收窄。下面的代码在C++03中合法,而在C++11中非法。
int arr[]={1.0};
这里1.0是一个double类型,使用它初始化int类型数组会导致数据收窄。因此在C++11中无法通过编译。
条目8 可能导致问题的隐式函数在C++11被定义为deleted。这些隐式函数不能被使用。而C++03中可以使用。比如说下面这段代码:
struct A{const int a;};
由于常量(const)a总是应该被静态初始化的,因此程序员应该为struct A提供一个构造函数来完成这样的初始化。在C++11中,遇到这种可能导致问题(would be ill-formed)的情况下,缺省构造函数将被删除,以提示用户可能存在问题。
条目9 C++11中去除了无用的关键字:export。
条目10 C++11中,模板嵌套时可以直接使用双右尖括号,C++03则需要空白字符填充尖括号。例如:
template<typename T>struct X{};
template<int N>struct Y{};
X<Y<1>>2>>x;
C++03中会解释为X<Y<(1>>2)>>x;==>X<Y<0>>x。
C++11中这是非法的声明,因为“X<Y<1>>”被视为有效的模板使用。
条目11 C++11引入了一些新的标准头文件:<array>、<atomic>、<chrono>、<codecvt>、<condition_variable>、<forward_list>、<future>、<initializer_list>、<mutex>、<random>、<ratio>、<regex>、<scoped_allocator>、<system_error>、<thread>、<tuple>、<typeindex>、<type_traits>、<unordered_map>、<unordered_set>。
还有一些新加入的和C兼容的头文件:<ccomplex>、<cfenv>、<cinttypes>、<cstdalign>、<cstdbool>、<cstding>、<ctgmath>、<cuchar>。
条目12 C++11中,swap方法从<algorithm>移到了<utility>中。
条目13 C++11加入了一个新的顶级namespace:posix。
条目14 通用属性中的标记符如carries_dependency、noreturn不能作为宏名。
条目15 C++03假设全局的new操作符只会抛出类型为std::bad_alloc的异常;而C++11允许全局的new操作符抛出其他类型的异常。
条目16 C++11要求errno变量是线程局部的,而不是全局的。
条目17 C++11支持轻量级的垃圾回收机制。
条目18 标准库中的仿函数(函数对象)不再继承自std::unary_function和std::binary_function。
条目19 标准容器要提供的size()成员函数要求是O(0)复杂度;C++03中std::list的成员size()允许线性复杂度。
条目20 C++11中改变了一些函数方法的原型,比如erase和insert的返回值类型iterator变成了const_iterator,resize函数的参数从传值改为了传引用。
条目21 C++11允许一些类和函数方法的实现不同于C++03,比如:std::remove、std::remove_if、std::complex、std::ios_base::failure。