C++标准库第二版笔记 2
微小但重要的语法提升
template表达式内的空格:
vector< list<int> >; // OK in each C++ version
vector<list<int>>; // OK since C++11
取消二异性的nullptr std::nullptr_t
void f(int);
void f(void*);
f(0) // calls f(int)
f(NULL) //calls f(int) if NULL is 0, ambiguous otherwise.
f(nullptr) // calls f(void*)
注意std::nullptr_t被视为一个基础类型。
以auto完成类型自动推导
auto i; // ERROR: cant deduce the type of i
auto l = [] ( int x )-> bool {...,}; // lambda type
// auto& 将尽可能保存原来的类型
const int a2 = 10;
auto &b2 = a2; // b2 is a const type
int a3 [] { 1, 2, 3 };
auto b3 = a3; // b3 is a pointer
auto & b7 = a3; // b7 is an array
一致性初始化(Uniform initialization)与初始列(Initializer List)
如今,C++标准化了初始行为。它依赖实际值(actual value)而非依赖类型。若不造成精度损失,则不算为窄化。浮点数到整数永远是一种窄化。
type var { 1, 2, 3 };
type var[] { 1, 2, 3 };
vector<string> var{ "Berlin", "New York", "Shanghai" };
// 而默认行为可以强迫造成初始赋值
int j{}; // j is initialized by 0
int * q{}; // q is initialized by nullptr
// 窄化(narrowing),也就是精度降低或造成数值变动丢失,对大括号不成立。
int x1(5.3); // OK
itn x2 = 5.3; // OK
int x3{ 5.0 } //ERROR
char c2{999999}; // ERROR if 99999 doesnt fit into a char
vector<int> v2 { 1, 2.3, 4, 5.6 }; // ERROR
std::initializer_list<>
void print( std::initializer_list<int> vals ) {
for (auto p = vals.begin(); p!=vals.end; ++p) {
std::cout<<*p<<"
";
}
}
print( { 1, 2, 3, 4, 5, 6, 7 } );
class p {
public:
P(int,int); // cons 1
P(std::initializer_list<int>); // cons 2
};
P p( 77, 5 ); // calls cons1
P q{ 77, 5 }; // calls cons2
P r{ 77, 5, 42 }; // calls cons2
P s = { 77, 5 }; // calls cons2
由于初始列的出现,现在explicit关键词已不局限于单个构造函数出现时的隐式转化。
class p {
public:
explicit P(int,int,int); // cons 1
P(std::initializer_list<int>); // cons 2
};
P w = { 77, 5, 42 }; // ERROR
// 同下失去隐式转化能力
void fp(const P&);
fp({11,22,3}); // ERROR