作者loveme00835 (高髮箍)
看板C_and_CPP
標題Re: [討論] 大家都怎麼學STL?
時間Sun Sep 25 19:04:43 2011
※ 引述《n91324 (不丹)》之銘言:
: 最近想開始學STL
: 因為學C++不會STL感覺就是少了很多東西
: 所以想說自己買書來看
: 侯捷的 C++標準程式庫 好像是不少人推荐的
這本'中譯本'不錯, 可以當字典查
: 入門看這本OK嗎?
: 順便想問一下大家都怎麼學STL的? 想學的動機又是什麼?
我的動機就是
不想寫跟同學一樣的程式碼, 常常看到這個:
for(
int i = 0; i < 10; i++ )
// 型態就定錯了
array[ i ] = 0;
之後又翻了一下文件, 發現有比較簡短的寫法:
memset( array, 0,
sizeof(array) );
C++裡則可以用:
std::fill( array, array + 10, 0 );
它為我帶來的不只是更簡潔的寫碼方式, 其實還有更高的可讀性
(雖然透過迭代器尋訪容器到
auto的出現才有改善一點點)
STL不只是Algorithms + Containers, I/O Stream也可以算在其
中, 只是它用到所謂Concepts的地方比較少, 在使用前你不只要
清楚 template function/class template 的基本語法, 甚至設
計的時候也要考慮到很多因素( 避免提供過大彈性導致發行後才
發現設計欠佳), 我就曾在學弟的程式碼中看到這個問題:
template <
class T>
T MyStack::pop()
{
if( !empty() )
return memory[ --top ];
return T(0);
}
在堆疊為空時, 學弟選擇的是回傳一個以零為初始值的物件而
非使用擲出例外的方式來取代, 這有什麼壞處?
MyStack<
int> int_stack;
// 沒問題
MyStack<
float> float_stack;
// 這...勉強可以
MyStack<std::string> str_stack;
// 有發現問題嗎?
另外這個函式也必須明確說明堆疊元素滿足何種Concepts, 如
果該概念不包含在現有的STL中, 那你必須要自己創一個, 以
上的例子即需要:
Copy Constructible
Zero Initializable
(可用零來初始化, 必要時必須解釋為
整數符號0)
更嚴苛的還要注意建構/解構子是否在該呼叫環境下可用(非私
有成員), 透過'泛型程式設計'可以訓練這一塊, 也可以比較
了解身為可以和STL Algorithms/Containers 銜接的東西, 需
要滿足何種條件.
我看的書主要挑
Addison-wesley 出版的
原文書(文字上細微的
語意差別, 中文無法表達), 像是
C++ In-Depth Series這系列
就不錯, 研究源碼首推Boost, 不過到你會用到再來看就好了,
因為當你需要寫很多碼來完成一件工作時, 首先考慮的應該是
換個語言寫.
: 因為學校老師基本上也不太會去教(STL不是很重要嗎@@?)
不教有部分是因為上面講到的設計議題, 要講完不曉得要多少
學分了, 再來是把C++寫得好像其他直譯器語言也是有人比較
不能接受, 我們系上的老師就是這樣@"@
: 問了一下學校的學長
: 發現很多學長也沒有特別去接觸
你眼中的C++ vs
他人眼中的C++
小弟剛上大學時就擔任寫程式給別人抄的角色, 剛開始修C語言
時還好都有人看得懂, 不過修C++時只要導入新特性就會有人開
始該該叫了(現在做研究學長也特別叮嚀我別寫模版). 你應該
視合作的對象來決定如何應用所學, 一輩子都不需要去碰到的
話, 當成興趣來玩就好了...
C++支援 OOP並不代表都要用物件來把資料抽象化, C++提供STL
也不代表你硬要apply它, 像是:
int q = 1;
std::for_each( array, array + 10, []( int &a ) {
a = q;
q *= 2;
}
);
這個部分 generate 就會比 for_each 適用, 因為它們對迭代
器的需求不太一樣(ForwardIterator/InputIterator), 編譯可
能會過, 卻不自覺寫出沒可攜性的程式.
--
★ ★ ★ ★
★ ★ ★ ███ ███ █ █▌█ ██◣ ███ ▋▋█ ★ ★ ★
█▂█ █▃█ █ ███ █▆█ █▄█ ███
★ ★ █ ◣ █ █ █ ▋██ █▆◤ ███ ███ ★ ★
Kim Jae Kyung Koh Woo Ri Cho Hyun Young Kim Ji Sook
φwindyhorse
No Eul Oh Seung A Jung Yoon Hye
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.121.197.115
※ 編輯: loveme00835 來自: 140.121.197.115 (09/25 19:31)
推 QQ29:請問for( int i 那個型態 要改成甚麼呢 09/25 20:53
→ diabloevagto:u_int 09/25 20:56
→ diabloevagto:array位址的變數不會有負 09/25 20:56
→ james732:我想 size_t 應該也可以? 09/25 20:57
推 stonehomelaa:size_t 09/25 22:05
推 Fenikso:可是用unsigned會不小心踩到一格洞 09/25 22:10
→ Fenikso:for(size_t i = n - 1; i >= 0; i--) {...} 爆炸 09/25 22:11
→ Fenikso:所以用signed int我覺得是比較好的選擇 09/25 22:11
推 tsiteowy:同意樓上 09/25 22:17
for 通常都是計數用的
for(size_t i = n - 1; i >= 0; --i)
/**/;
以上的敘述雖可以反著尋訪元素, 但也多出了 n - 1 這樣離奇的敘述,
如果正向/反向交互使用, 個人覺得code會雜亂許多, STL 提供
std::reverse_iterator 配接器, 且多數容器皆提供rbegin()、rend()
, 不用因判斷邊界條件錯誤而當機, 所以還蠻方便的!
FIDS 加入了 std::array 模版, 更減少了魔法數字的使用
※ 編輯: loveme00835 來自: 140.121.197.115 (09/25 23:24)
推 Fenikso:當然是用iterator最好 09/25 23:32
→ Fenikso:只是看到很多人推size_t, 這樣寫真的要很小心.. 09/25 23:33
推 tropical72:love大那段size_t loop,指出了我在 C 還是選int的理由 09/25 23:46
→ uranusjr:for 迴圈計數器要用什麼形態是千古戰文, 挑別人這個錯誤 09/26 09:19
→ uranusjr:實在沒有意義, 第一部份會讓很多人莫名其妙中槍 -_- 09/26 09:19
推 developers:推C++ In-Depth Series,還有Meyers的Effective series 09/26 09:57
推 klandor:我有聽說有部門內部規定for一定要反向寫的 因為效率問題 09/26 23:37
推 tropical72:@klandor:反向效率會較佳的可能是? zero flag? 或其他? 09/26 23:39
→ firejox:減比加快 (我猜) 09/26 23:52
推 tropical72:減比加快??我以為減法器 ret要考慮補數問題比較慢說 XD 09/26 23:56
推 farmerlu:減和加是一樣快的, 但加/減之後要做判斷, 則減有可能快. 09/27 00:47
→ farmerlu:因 x86 組合語言有 loop 這個指令,減完會順便判斷到0了嗎 09/27 00:48
→ farmerlu:不知是不是指以上 compiler / 組語 的原因 ? 09/27 00:49
推 Ross0916:我沒有看過 compiler 編出 loop 指令的 原因不知@@ 09/27 01:17
→ Ross0916:應該不差那麼一點吧 還有 inc/dec 比 add/sub 慢.... 09/27 01:18
推 littleshan:loop只能跳前後128byte,現代的compiler早就沒在用了 09/27 01:19
→ cgcheng:inc/dec要比add/sub快吧?inc/dec最基本的 09/27 03:00
推 littleshan:其實是一樣快的 09/27 10:41
推 Ross0916:真的嗎 我是看某個 optimisation manual 看到的...忘了 09/27 18:46
推 cgcheng:google一下就有了,差1個clock你要說一樣快也ok 09/28 00:25
→ cgcheng:之後的cpu也沒在列這種東西,幾個cycle已經不重要 09/28 00:26
推 littleshan:latency 都是一個 clock 啊,你找到的是哪篇? 09/28 02:52
推 chienweichih:朝聖推學長XD 12/10 01:16