【侯捷-c++11新特性-】
variadic templates
uniform initialization
initializer lists
alias template
用例
void
print()
template
<
typename t,
typename..
. types>
void
print
(const t& firstarg,
const types&..
. args)
void
main()
c++11之前,變數的初始化操作可以用小括號,大括號,或者是賦值操作。常常使人困惑。在c++11之後,提供統一的大括號初始化方式。
用例
void
main()
; vector<
int> v
; vector cities
; complex<
double
> c
;}
兩個注意點int i;
// i 沒有被初始化
int j
;//j 被初始化為 0
int*p;
//p沒有被初始化
int*q
;//q被初始化為空指標
intx1(
5.3)
;//warning
int x2 =
5.3;
//warning
int x3
;//error, 收縮轉換報錯
int x4 =
;//error, 收縮轉換報錯
char c
;//ok
char c2
;//error
vector<
int> v1
;//ok
vector<
int> v2
;//error
用例
void
print
(initializer_list<
int> vals)
}void
main()
);}
原始碼template
<
class
_elem
>
class
initializer_list
constexpr
initializer_list
(const _elem *_first_arg,
const _elem *_last_arg)
noexcept
:_first
(_first_arg)
,_last
(_last_arg)
_nodiscard constexpr
const _elem *
begin()
const
noexcept
_nodiscard constexpr
const _elem *
end(
)const
noexcept
_nodiscard constexpr size_t size()
const
noexcept
private
:const _elem *_first;
const _elem *_last;
};
initializer_list 在標準庫中的應用template
<
class
_ty>
_nodiscard constexpr _ty (max)
(initializer_list<_ty> _ilist)
//vector 的 insert 方法之一
iterator insert
(const_iterator _where, initializer_list<_ty> _ilist)
用例
template
<
typename t>
class
myalloc
;template
<
typename t>
using vec = std::vector>
;
之後就可以直接使用:
vec<
int> vec;
注意點
不能為你自己寫的模板別名寫偏特化或者全特化。
使用 #define 無法達到該目的
#define vectemplatestd::vector>;
那麼 vecvec 等價於:
template
<
typename
int> std::vector<
int, myalloc<
int>>
;
顯然不對
使用 typedef 也無法達到目的,它不能實現模板別名,只能實現:
typedef std::vector<
int, myalloc<
int>> vec
應用
比如說我現在想實現這樣乙個目的:寫乙個函式,這個函式能夠對傳入的容器進行複製,返回乙個新的容器,傳入的容器可能是 vector,list等任何擁有 push_back成員函式的容器。
初步的想法可能是這樣子的,想通過模板類實現:
template
<
typename container,
typename t>
container
copycontainer
(container container, t item)
但是此時編譯器會報錯,說 模板引數 「container」 不能包含模板引數列表。因為編譯器無法判斷出模板引數container是模板,所以報錯。
那麼這個時候,我們可能又會想到使用模板的模板,把 container定義為乙個模板,同時又作為乙個模板引數。**如下:
template
<
typename t,
template
<
typename
>
typename container>
container
copycontainer
(container container)
這個時候能夠編譯通過,讓我們來使用試試:
vector<
int> v
;auto copy =
copycontainer
(v);
這個時候,編譯器又會報錯,說沒有與引數列表匹配的 函式模板 「copycontainer」 例項,這又是為什麼呢??
究其原因,其實是這樣的:傳入的引數是 vector容器,而vector容器的定義是這樣子的:
template
<
typename _ty,
typename _alloc = allocator<_ty>>
class
vector
;
它是需要兩個模板引數的,而我們在 copycontainer 函式中所定義的模板引數container只有乙個模板引數 t,而沒有相對應的 allocator,因此報錯。
我們或許可以這樣改:
template
<
typename t,
template
<
typename f,
typename _alloc = allocator>
typename container>
container
copycontainer
(container container)
但是這個時候,其實就可以使用 alias template 了:
template
<
typename t,
template
<
typename
>
typename container>
container
copycontainer
(container container)
template
<
typename t>
using vec = vector>
;int
main()
;auto copy = copycontainer<
int, vec>
(v);
return0;
}
注:
其實如果是想獲得容器中的元素型別,其實也可以用 iterator 的萃取機去獲得,**如下:
typedef
typename std::iterator_traits<
typename container::iterator>
::value_type valtype;
valtype 就是容器類的元素型別。 C 11新特性學習
lambda表示式用於建立匿名的函式物件,語法為 函式可訪問的的外部變數 函式引數 返回值型別 如 int a 1,b 2 int c b int x int b 表示函式中可以訪問外部變數b,而且引數b是按值傳遞,b 表示引數b是按引用傳遞,表示可以訪問所有外部變數,並且是用按值傳遞方式,類似,也...
C 11 新特性試用
在c 11之前,auto關鍵字用來指定儲存期。在新標準中,它的功能變為型別推斷。auto現在成了乙個型別的佔位符,通知編譯器去根據初始化 推斷所宣告變數的真實型別。各種作用域內宣告變數都可以用到它。例如,名空間中,程式塊中,或是for迴圈的初始化語句中。auto i 42 i is an int a...
C 11 新特性總結
vs2012以上版本支援 一.auto的使用 auto func less 自動表示函式指標 auto ite vector a.begin 自動表示stl的迭代器 auto p new foo 自動表示變數指標等變數 二.decltype int x 3 decltype x y x 從變數或表示...