【C++】 C++11 新特性

Header files

C++2.0 新特性包括語言和標準庫兩個方面,後者以 header files 形式呈現。ios

  • C++ 標準庫的header files不帶.h,例如: #include <vector>
  • 新式 C header files 不帶.h,例如: #include<cstdio>
  • 舊式 C header files (帶有.h) 仍可用,例如:#include <stdio.h>

編譯器對 C++2.0 的支持

  • C++11
#define __cplusplus 201103L
  • C++98 & C++03
#define __cplusplus 199711L

編程實驗

文件:Test.cppexpress

#include <iostream>

using namespace std;

int main()
{
    cout << __cplusplus << endl;

    return 0;
}

輸出:編程

201103

Variadic Templates (可變參數模板)

  • 《Primer C++》中文版第五版 918 頁。
// 遞歸出口
void print()
{
}

template <typename T, typename... Types>
void print(const T &firstArg, const Types&... args)
{
    cout << firstArg << endl;   // 打印第一個參數
    print(args...);             // 對其他的參數調用 print
}
template <typename... Types>
void size(const Types&... args)
{
    cout << "args number : " << sizeof...(args) << endl;  // 產生參數數量
}

... 就是一個所謂的 pack 包函數

  • 用於 template parameters, 就是 template parameters pack(模板參數包)
  • 用於 function parameter types, 就是 function parameter types pack(函數參數類型包)
  • 用於 function parameters,就是 function parameter pack (函數參數包)

1_meitu_1.jpg

2_meitu_2.jpg

編程實驗

文件: main.cppspa

#include <iostream>
#include <bitset>

using namespace std;

// 遞歸出口
void print()
{
}

template <typename T, typename... Types>
void print(const T &firstArg, const Types&... args)
{
    cout << firstArg << endl;   // 打印第一個參數
    print(args...);             // 對其他的參數調用 print
}

template <typename... Types>
void size(const Types&... args)
{
    cout << "args number : " << sizeof...(args) << endl;  // 獲取參數數目
}

int main()
{
    print(7.5, "hello", bitset<16>(377), 42);

    cout << endl;

    size(1,2,3,4,5,6);

    return 0;
}

輸出:指針

7.5
hello
0000000101111001
42

args number : 6

Spaces in Template Expressions

vector<list<int> >;  // OK in each C++ version
verctor<list<int>>;  // OK since C++11

nullptr and std::nullptr_t

C++11 lets you use nullptr instead 0 or NULL to specify a pointer refers to no value(which differs from having an undifined value). This new feature especially helps to aviod mistakes that occurred when a null pointer was interpreted as an integral value. For example:

(C ++ 11容許您使用nullptr而不是0或NULL來指定一個指針不指向任何值(這與具備未定義的值不一樣)。 此新功能特別有助於避免在將空指針解釋爲整數值時發生的錯誤。)code

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*)
nullptr is a new keyword. It automatically converts into each pointer type but not to any integral type. It has type std::nullptr_t, definedin <cstddef> (see Section 5.8.1,page 161), so you can now even overload operations for ths case that a null pointer is passed. Note that std::nullptr_t counts as a fundamental data type (see Section 5.4.2, page 127).

(nullptr是一個新關鍵字。 它會自動轉換爲每種指針類型,但不會轉換爲任何整數類型。 它的類型爲std :: nullptr_t,在<cstddef>中定義(請參閱第5.8.1節,第161頁),所以對於傳遞空指針的狀況,您如今甚至能夠重載操做。 請注意,std :: nullptr_t被視爲基本數據類型(請參見第5.4節,第127頁)。)orm


【標準庫中 nullptr_t 的定義】文件:stddef.h對象

#if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED)
namespace std { typedef decltype(nullptr) nullptr_t; }
using ::std::nullptr_t;

編程實驗

文件:Test.cppblog

#include <iostream>

using namespace std;

void f(int i)
{
    cout << "void f(int i) : " << i << endl;
}

void f(void *p)
{
    cout << "void f(void *p) : " << p  << endl;
}

int main()
{
    f(0);
    // f(NULL);
    f(nullptr);

    return 0;
}

輸出:

void f(int i) : 0
void f(void *p) : 0

注: f(NULL) 編譯輸出

error: call of overloaded ‘f(NULL)’ is ambiguous
     f(NULL);
           ^
test.cpp:5:6: note: candidate: void f(int)
 void f(int i)
      ^
test.cpp:10:6: note: candidate: void f(void*)
 void f(void *p)

Automatic Type Deduction with auto

With C++11, you can declare a variable or an object without specifying its specific type by using auto. For example:

(使用C ++ 11,能夠經過使用auto來聲明變量或對象,而無需指定其特定類型。 例如:)

auto i = 42;    // i has type int
double f();
anto d = f()    // d has type double
Using auto is especially useful where the type is a pretty long and/or complicated expression. For example:
vector<string> v;

auto pos = v.begin();   // pos has type vector<string>::iterator
auto I = [](int x)->bool{   // I has the type of a lambda
    // ...                  // taking an int and return a bool
}
The latter is an object, representing a labda.

【標準庫中 auto 的使用】文件:stl_iterator.h

#if __cplusplus >= 201103L
    // DR 685.
    inline auto
    operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
          const __normal_iterator<_IteratorR, _Container>& __rhs) noexcept
    -> decltype(__lhs.base() - __rhs.base())
#else
    inline typename __normal_iterator<_IteratorL, _Container>::difference_type
    operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
          const __normal_iterator<_IteratorR, _Container>& __rhs)
#endif

編程實驗

文件:Test.cpp

#include <iostream>
#include <list>
#include <string>
#include <algorithm>

using namespace std;

void func1()
{
    list<string> c = {"a", "b", "c"};

    list<string>::iterator ite;
   ite = find(c.begin(),  c.end(), "a");

    if (ite != c.end())
    {
        cout << *ite << endl;
    }
}

void func2()
{
    list<string> c = {"a", "b", "c"};

   auto ite = find(c.begin(),  c.end(), "a");

    if (ite != c.end())
    {
        cout << *ite << endl;
    }
}

int main()
{
    func1();

    func2();

    return 0;
}

輸出:

a
a

更新中。。。

相關文章
相關標籤/搜索