C 11 14 簡易推薦小記

2021-07-08 16:49:33 字數 3838 閱讀 4608

之前了解過一些c++

新標準的內容,覺得很不錯,在此寫篇小記,簡易推薦一下~

容器內元素操作是個很普通的需求,工作中應是屢見不鮮,這裡假設有個list

容器,儲存的是一系列

intc++

表達一下,大概是這個樣子:

#ifndef __test_1_h__

#define __test_1_h__

#include #include void add_one(int& val)

void add(std::list& l)

}void print_one(const int& value)

void print(const std::list& l)

std::cout << std::endl;

}void test() ;

std::listl;

for (int i = 0; i < sizeof(ages) / sizeof(int); ++i)

print(l);

add(l);

print(l);

}#endif

簡單看看,似乎寫的還行:**格式統一,函式命名也相對明確,引數上使用了(常量)引用來傳遞,效率上應該不錯,訪問容器元素使用了迭代器,模式上很經典呀~

不過仔細再看,那幾個迭代器的宣告還是略顯冗長了一些,list

容器的初始化也不是那麼簡明,更大的乙個問題是,**沒啥通用性,容器型別換一下,**大抵得重寫,而且內容都是重複的~

好吧,既然問題找到了,那就來嘗試改善一下:迭代器的宣告可以用typedef

簡化,不過更好的自然是直接迴避迭代器宣告,這裡我們剛好可以借助

std::for_each

來達到目的,

list

的初始化可以改用迭代器版本的建構函式,可以節省不少**,至於通用性的問題,模版幾乎都是標準答案~

一陣改造之後,**大概成了這樣:

#ifndef __test_2_h__

#define __test_2_h__

#include #include #include #include templatevoid add_one(t& val)

templatevoid add(container& container)

templatevoid print_one(const t& value)

templatevoid print(const container& container)

void test() ;

std::listl(ages, ages + sizeof(ages) / sizeof(int));

print(l);

add(l);

print(l);

std::vectorv(ages, ages + sizeof(ages) / sizeof(int));

print(v);

add(v);

print(v);

}#endif

改造後的**感覺已經不錯了,沒有冗長的迭代器宣告,沒有累贅的初始化過程,通用性也不錯,容器換做vector

,**一樣工作~

那麼問題來了:上面的**還能更簡潔嗎?

答案是可以!

先上**:

#ifndef __test_3_h__

#define __test_3_h__

#include #include #include #include void test() ;

auto add = [&add_one](auto& container) ;

auto print_one = (const auto& val) ;

auto print = [&print_one](const auto& container) ;

std::listl = ;

print(l);

add(l);

print(l);

std::vectorv = ;

print(v);

add(v);

print(v);

int a = ;

print(a);

add(a);

print(a);

}#endif

不太了解c++

新標準的同學現在可能已經在心裡暗罵了:什麼鬼?!不急,咱們一行行來看:

auto add_one = (auto& val);

auto 本來便是

c++中的乙個關鍵字,用於自動變數的宣告(雖然我從來也沒用過),在

c++11

中,它的作用(之一)變成了自動型別推導,還記得最早的那個迭代器宣告嗎:

std::list

::const_iterator beg = l.begin();

使用auto

的話只要這麼寫就行了,很舒服:

auto beg = l.begin();

所以這裡我們就是定義了乙個自動型別推導的add_one

變數,至於後面那個詭異的初始化表示式:

(auto& val)

其實是c++11

新引入的

lambda

表示式,用以方便的就地定義匿名函式物件,以上面的**為例來簡單說明一下:

中用於定義捕獲子句,至於什麼是捕獲子句,我們暫時不管,反正這裡我們什麼都沒填~

(auto& val

)則是引數列表,這個對於我們就很親切熟悉了,至於為什麼引數寫成

auto&

,而不是

int&

之類的方式,其實是使用了

c++14

中新定義的通用

lambda

功能,個人認為可以理解為定義模版,即 

auto& val 

可以看作

t& val

,用於匹配不同型別~

至於{ ++val; 

}就是函式體了,沒啥好說的,一目了然~

ok,現在為止,

add_one

的定義就清楚了,簡單來說,它其實就是乙個接受單個引數的函式物件~

add_one搞明白了,那麼

add自然也大概清楚了:

auto add = [&add_one](auto& container) ;

這裡我們用到了c++11

以來新增的初始化列表,簡單來說就是,新標準的標準庫容器都新增了乙個以

initializer_list

為引數的建構函式,上述表示式中的

會被構造為乙個

initializer_list

並傳入list

的建構函式,之後便是一般的初始化流程了

~可以看到,初始化列表的引入讓容器的初始化變得非常簡潔,並且對於非標準庫的容器,你也可以為它定義以

initializer_list

為參的建構函式,同樣可以使用上面的初始化方式~

至此,我們使用更少的**,更簡潔易讀的表達出了程式邏輯,並且程式的通用性更強,而且程式的效率並沒有任何損失,cool~

c++新標準還遠遠不止上面提到的內容,像

nullptr

,override

,final

等新加入的關鍵字也很貼心,更有像智慧型指標、

move

語義等強大的工具加盟,當然了,另有一些個人感覺頗為晦澀的東西引入(

memory order etc.

),但是管他呢,慢慢了解便是,總體上,個人強烈建議有興趣的童鞋了解學習

c++新標準,

這裡就是個很好的開始~

C 11 14特性備忘

template auto add t x,u y int array for auto x array include 建構函式列表初始化 class magic magic magic std vector int v 普通函式形參 void func std initializer list ...

C 11 14 自動型別推導 auto

從c 11起,auto關鍵字不再表示儲存型別,而是成為了隱式型別定義關鍵字,其作用是讓編譯器在編譯期 便自動推斷出變數的型別。例如 auto a 1 a 為 int 型變數 auto ptr new auto 1 auto 1 int 1 ptr 為 int 型指標變數 const auto q a...

C 11 14之可變參模板

可變參類模板 variadic template 允許模板中有0到任意個模板引數 t emplate typename.t void myfunc t.ar s myfunc 0 0 myfunc 11 23 2 2 myfunc 14 12.4 nj 3 4 4 ar s 稱為一包或者一堆引數,這...