上文http://blog.csdn.net/zy498420/archive/2010/11/09/5998427.aspx提到的「播種」之法需要你手動指定目標型別,稍微還是有點羅嗦(et_seed,字母還是挺多的),然而為什麼需要指定呢?
原因:如果不指定,最終生成的樹可能根本不知道應該轉換為何種型別,dest_type 未知。
那麼把 inline operator binary_op::dest_type () const;
改為 template inline operator binary_op::t() const;不行嗎,在「=」的時候自動選擇t的型別?
答案:不行。「=」左邊的操作物件可能有多種單引數建構函式。以std::string為例,t可以為string也可以為const char*,他們的函式過載決議的地位是平等的,這時候就產生了二義 性,編譯器不知道該如何選擇。
那麼我們就一定要一開始就顯示指定嗎目標型別?
答案:不一定。我們只需要保證第一棵樹的構造時,目標型別能被指定。
這下問題的本質就出來了:如果種子不攜帶目標型別資訊,而且第一次的操作物件恰好不是目標型別,那麼這棵樹就永遠也沒有機會得知目標型別了。
strb = et_seed() + 「1234567890"+ str1+ str2 + string("3 ");
如上,第一步et_seed() + 「1234567890",假設et_seed不攜帶資訊std::string,et_seed<??>() + 「1234567890"的結果根本不知道他需要轉化成string!
那麼話又說回來,而且第一次的操作物件是目標型別(我想這其實也是多數情況),那麼我們就可以不指定而靠模板函式自動讀取操作物件的型別來獲得目標型別了。
strb = et_seed<??>() + str1+「1234567890"+ str2 + string("3 ");
我乾脆給它取了個新名字any_seed
struct any_seed: et_seed{};
然後其它地方修修補補,幫助函式過載決議就搞定了。
然而我們不能寄希望使用者總是明智的,如果使用者strb = any_seed() + 「1234567890"+ str1+ str2 + string("3 ");這樣的情況下使用any_seed,生成的樹將錯誤的認為目標型別是char [11]而不是string,直到最後該賦值了編譯器才發現不能對char [11]做+=操作,然後口吐蓮花,噴出500多k的超長錯誤資訊(最終生成的樹型別名字可能長達幾個螢幕)......
我可不想被使用者罵死。
終極方案出爐:種子皮
template
inline _et_private::binary_op
any_seeder(const d& arg)
strb = any_seeder(str1)+「1234567890"+ str2 + string("3 ");
strb = 「1234567890" + any_seeder(str1)+ str2 + string("3 ");
哦,我的天,這完全是乙個思維的革新,不是嗎?我們的改良方式從播種,變為了披上種子皮!!
原來總是需要麻煩的進行"+",這下只需要找準披種子皮的物件!!nice !mem_func_ref,bind1st的思維方式又一次大放異彩!筆者在寫完前一篇文章一小時之內就又有了新靈感,慶祝一下。
其實原來的種子完全可以不開放給使用者使用了,種皮完全可以勝任,不過我還是保留了他在私有名字空間之外,留給大家觀摩。
(最新版本請閱讀):
字串最長子串難?滑動視窗拯救你
給定乙個字串,請你找出其中不含有重複字元的 最長子串 的長度。示例 1 輸入 s abcabcbb 輸出 3 解釋 因為無重複字元的最長子串是 abc 所以其長度為 3。子串 串中任意個連續的字元組成的子串行稱為該串的子串。要求字串的不含有重複字元的最長子串的長度,只需要先找到最長子串然後再求其長度...
加密你的字串
using system using system.collections.generic using system.text using system.security.cryptography using system.io namespace encryption 加密資料時用的建構函式 系統...
字串的統計字串
給定乙個字串,統計每乙個字母的出現次數 比如aabbccc,列印出來就是a 2 b 2 c 3 思路還是採取遍歷,注意這幾個題的思路都比較類似 要注意這裡的sstream 這裡的clear 並非清空了緩衝區,而只是重置標誌,如果要重置緩衝區,則應為ss.str include include usi...