@溪流
1.
這是C++的缺陷…… 當(dāng)初可能沒(méi)想到模板會(huì)被這么用,所以模板的功能其實(shí)還比較弱。
即使比較弱,也比java和C#強(qiáng)大,它是真正的代碼生成器……
C#的模板有一些約束,java的根本就是垃圾……
所以,模板還是很復(fù)雜的……
更本質(zhì)的說(shuō),其實(shí)體現(xiàn)的是一種ducking type,以單一函數(shù)作為組件之間交互的接口,而不是整個(gè)類型。ruby、python、lua這種動(dòng)態(tài)類型語(yǔ)言都支持ducking type。而C++的模板只支持編譯時(shí)的ducking type。
C++社區(qū)給這種使用方式取了一個(gè)新的名字,叫concepts……
ducking type可能屬于新東西,而且很可能是意外產(chǎn)物(比如C++、python、lua;ruby好像是設(shè)計(jì)之初就考慮到這種用法),所以沒(méi)有提供專門的、顯示的通過(guò)短小的代碼(比如interface聲明)就可以表達(dá)的方式。只能通過(guò)文檔了……
說(shuō)穿了,那些抵觸這種設(shè)計(jì)的,要么是偷懶不想看文檔,要么是已經(jīng)學(xué)會(huì)OO就不想學(xué)任何其他新事物,要么就是理解能力不夠……
心里疙瘩放下吧……
1.1. 雖然沒(méi)有專門的語(yǔ)法支持,但語(yǔ)言還是會(huì)檢查的,比如C++編譯時(shí)出錯(cuò),其他3個(gè)語(yǔ)言運(yùn)行時(shí)出錯(cuò)。
1.2. 比如python標(biāo)準(zhǔn)庫(kù)中,序列就沒(méi)有單獨(dú)的size()成員。所有的序列都通過(guò)len得到長(zhǎng)度。已經(jīng)開(kāi)始向這種思想靠攏了。
1.3. stl也這么多年了……
2
我對(duì)0依賴的看法不是"難",而是"通常沒(méi)有必要"。
應(yīng)該盡可能復(fù)用已有的優(yōu)秀的代碼。
盡可能向已有的,還過(guò)得去不算垃圾的標(biāo)準(zhǔn)靠攏,而不是自己獨(dú)立發(fā)明一套,結(jié)果在實(shí)際應(yīng)用中無(wú)法融合。
當(dāng)然,這和練習(xí)編程技巧相抵觸……
所以我想提出一些建議,既可以練習(xí);并且練習(xí)的結(jié)果是可以真正派上用場(chǎng)的。
比如,你可以考慮實(shí)現(xiàn)這樣一個(gè)函數(shù):
int vprintf_parse(void (*handler)(const char* s,void* context),void* context
const char* format, va_list arg );
按vprintf的標(biāo)準(zhǔn)去解析format與arg。每處理完一個(gè)%就調(diào)用handler一次。
由handler去考慮將s"輸出"到哪里。
這樣的話,vprintf_parse就可以用于很多很多地方:傳遞不同的hanlder給它就行。
當(dāng)然,你也可以用它來(lái)實(shí)現(xiàn)string.format。 但一定要將vprintf_parse暴露出來(lái),否則窩在string.format中太暴殄天物了。
更進(jìn)一步…… 還可以提供一些讓客戶代碼擴(kuò)展的機(jī)制,讓它自己定義%后的轉(zhuǎn)義符,以及處理方式。
3
我的意思是,這種方式是行不通的。
你要插入的元素是T吧?
std::set<std::list<T> > 元素是 std::list<T> 哦, 不是T了。
比較也是按std::less<std::list<T> >比較,而不是T。
不管multiset的底層實(shí)現(xiàn)是rbtree還是rbtree+list,都需要真正定義一個(gè)類,將底層實(shí)現(xiàn)的接口adapt一下才行。僅僅typedef是不夠的……
回復(fù) 更多評(píng)論