ch3.1 new c++11 language features
3.1.1 important minor syntax changes
- space in template expression
vector< list<int> > // ok in each c++ version
vector< list<int>> // ok since c++11
- nullptr & std::nullptr_t c++11 uses nullptr instead of 0 or NULL to specify a pointer refers to no value(not undefied value) to avoid mistakes , a null pointer being interpreted as an integral value.
nullptr can automatically convert to any pointer type but not integral type.It's a std::nullptr_t type which is a fundamental data type defined in <csstddef>.
void f (int);
void f(void *);
f(0);//ok f(int) called
f(NULL);//ok f(int) is called if NULL is 0,ambiguous otherwise
f(nullptr);//ok f(void *) called
3.1.2 automatic type deduction with auto
- auto
c++11 enables you to declare varibles or objects without specifying its type using atuo(in c auto was used to declare varibles as local contrast with static.It's fewly used store type due to not specifying something as static ,it's defaultly declared as auto).
auto i=0;// ok i has type int
double f(void);
auto d=f();//ok i has type double
ΔThe type of varibles or objects are deduced by its initializer ,thus initialization is necessary when using auto .And additional qualifiers are allowed before auto.
auto i;// Error initialization expected
static auto d=0.66;//ok qualifiers allowed
Using auto is especially useful when the type is prety long or the expression is complicated.
vector<string> v;
...
auto pos=v.begin();// pos has type of vector<string>::vector_iterator
auto l=[ ] (int) -> bool {
...... // l has a type of lambda
...... // taking a int and returning a bool
}
3.1.3 uniform initialization & initializer lists
- uniform initialization
Initialization could happen with parentheses ,braces or assignment operators which usually confuses novices.For this reason ,c++ 11 introduced the concept of uniform initialization which means using a common syntax using braces for any initialization.
int values[ ] {1,2,3};
std::vector<int> v{1,2,15,1};
std::vector<std::string> cities{"newyork","suzhou","nanjing"};
std::complex<double> c{4.0,6.0};//equivalent to c(4.0,6.0)
- initializer lists
initializer lists forces so-called value initialization,which means even local fundamental type are initialized by zero or nullptr.(Usually local fundamental type would be undefined value if not explicitly initialized and user defined type would be initialized by its default.While gloabal things' elements would be initialized with 0 or nullptr .)
struct s{
int i=0;
int ui;
char c='a';
char uv;
};
{//local varibles
int i;// i has undefined value
int j{};//j has value 0
int *p;//p has undefined value
int *q{};//q has value nullptr
s stc;// i=0 ;ui =undefined value;c='a';uc=undefined value;
// In local user defined type foundamental type has default value will be initialized with its default value ,otherwise will be undefined values.
}
Narrow initialization isn't allowed with braces .If a value can be represented exactly by target type,the conversion isn't narrowing,otherwise is narrowing.Notes that conversion from float type to integer type is always narrowing,even 7.0 to 7.
int x1(5.3); //ok but ouch:x1 becomes 5
int x2=5.3;//ok but ouch:x2 becomes 5
int x3{5.0};//error :narrowing
int x4={5.3};//error:narrowing
char c1{7};//ok : Though 7 is an int, char type can represent it , this is not narrowing.
char c2{99999};//error :narrowing (99999 doesn't fit into a char)
std::vector<int> v1{1,2,4,5};//ok
std::vector<int > v2{1,2.0,4,5};//error:narrowing
wating for updating....