C++11 带来的新特性 (1)
1 语法改进
1.1 模板表达式中的空格
- 在c++03 及以前
vector<list<int>>; //Error
vector<list<int> >; //OK
- c++11
vector<list<int>>; //OK
1.2 nullptr 和 std::nullptr_t
- 在c++03 及以前
void f(int);
void f(void*);
f(0); //call f(int)
f(NULL); //有歧义
- c++11
f(nullptr);//call f(void*)
nullptr是关键词,其类型是std::nullptr_t
2 auto-自动类型推断
auto i = 42; //int
double f();
auto d = f(); //double
auto n; //Error
static auto vat = 0.19;
vector<string> v;
auto pos = v.begin();
auto f = [](int x)-> bool{return x+1;}
3 for循环
基本形式:
for( decl : coll ){
statement
}
等价于:
for( auto _pos = coll.begin(), _end = coll.end(); _pos != NULL; ++_pos){
decl = * _pos;
statement
}
或者(其中begin()和end()是全局函数):
for( auto _pos = begin(coll), _end = end(coll); _pos != NULL; ++_pos){
decl = * _pos;
statement
}
- 示例1
for( int i : {2, 3, 4, 5,8} ){
std::cout<< i << std::endl;
}
- 示例2。使用引用方式,修改容器中的元素。
std::vector<double> vec;
...
for( auto & elem : vec ){
elem *= 3;
}
- 示例3。结合模板,同时使用const修饰元素。
template < typename T>
void printElements( const T& coll ){
for( const auto& elem : coll ){
std::cout<< elem << std::endl;
}
}
- 示例3。结合模板,同时使用const修饰元素。
template < typename T>
void printElements( const T& coll ){
for( const auto& elem : coll ){
std::cout<< elem << std::endl;
}
}
- 示例4。range方式使用for循环,会调用拷贝构造函数。
Get() const{
return m_data;
}
private:
int m_data;
};
ostream& operator<<(ostream& os, const X& x)
{
os << x.Get();
return os;
}
int main(){
vector<X> v = {1, 3, 5, 7, 9};
cout << "\nElements:\n";
for (auto x : v)
{
cout << x << ' ';
}
return 0;
}
输出:
X copy ctor.
X copy ctor.
X copy ctor.
X copy ctor.
X copy ctor.
Elements:
X copy ctor.
1 X copy ctor.
3 X copy ctor.
5 X copy ctor.
7 X copy ctor.
9
为了防止调用拷贝构造函数,提高下率,加上引用。
for (auto &x : v)
{
cout << x << ' ';
}
执行输出:
X copy ctor.
X copy ctor.
X copy ctor.
X copy ctor.
X copy ctor.
Elements:
1 3 5 7 9
发现已经不调用拷贝构造函数了。
- 反面示例。在for循环中,不能显示调用(使用explicit)类型转换函数:
class C {
public :
explicit C( const std::string & s); //显示转换
...
};
int main(){
std::vector<std::string> vs;
for( const C& elem : vs ){
std::cout << elem << std::endl;
}
}
报错。去掉“explicit”后,可正常运行。
invalid initialization of reference of type ‘const C&’ from expression of type ‘std::__cxx11::basic_string<char>’
4 字符串
- 原始字符串
在字符串前面加上关键字R,表示这是一个原始字符串。
下面这两个是等效的。
"\\\\n"
R"\\n"
下面这两个也是等效的。
R"nc(a\
b\nc()"
)nc";
"nc(a\\\n b\\nc()\"\n )nc";
- 编码的字符串
使用编码前缀制定字符串编码。如下
L"hello" // 定义wchar_t编码的字符串
前缀有以下几种:
- u8表示UTF-8编码。
- u表示char16_t
- U表示char32_t
- L表示宽字符集,类型wchar_t
5 强枚举类型
c++11中的枚举类型如下所示:
enum class Salutation : char { mr, ms, co, none };
- 与int类型之间显示转换是不允许的。
- 使用 Salutation::mr 方式引用枚举类型。
- 可以显示的指定一个后台类型,如上例中的char。如果不显示指定,默认是int类型。
待续。。。