青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-90  評論-947  文章-0  trackbacks-0

如果要 typedef,搞出來的都是些很惡心的名字,自己看了也生氣,還是不搞好了,就 size_t 和 int 玩到底吧。

把 Array 的接口又改得一塌糊涂了,重新貼一下:

namespace xl
{
   
template <typename ValueType>
   
class Array
   
{
   
public:
       
Array(size_t nSize = 0);
       
Array(size_t nSize, const ValueType &tValue);
       
Array(const Array<ValueType> &that);
        ~
Array();

   
public:
       
class Iterator
       
{
       
public:
           
Iterator();
           
Iterator(ValueType *pValue);
           
Iterator(ValueType *pValue, ValueType *pStart, ValueType *pEof);
           
Iterator(const Iterator &that);

       
private:
           
ValueType *m_pStart;
           
ValueType *m_pEof;
           
ValueType *m_pCurrent;

       
public:
           
ValueType &operator * ();
           
ValueType *operator -> ();

       
public:
           
Iterator &operator = (const Iterator &that);
           
bool operator == (const Iterator &that) const;
           
bool operator != (const Iterator &that) const;

       
public:
           
Iterator &operator ++ ();
           
Iterator operator ++ (int);
           
Iterator &operator -- ();
           
Iterator operator -- (int);

       
public:
           
Iterator operator +(int nDistance) const;
           
Iterator operator -(int nDistance) const;
           
Iterator &operator +=(int nDistance);
           
Iterator &operator -=(int nDistance);
        };

       
class ReverseIterator : public Iterator
       
{
       
public:
           
ReverseIterator &operator ++ ();
           
ReverseIterator operator ++ (int);
           
ReverseIterator &operator -- ();
           
ReverseIterator operator -- (int);
        };

   
public:
       
Iterator Begin() const;
       
Iterator End() const;
       
ReverseIterator RBegin() const;
       
ReverseIterator REnd() const;


   
public:
       
Array<ValueType> &operator=(const Array<ValueType> &that);
       
bool operator==(const Array<ValueType> &that) const;
       
bool operator!=(const Array<ValueType> &that) const;

   
public:
       
ValueType &operator[](size_t nIndex);
       
const ValueType &operator[](size_t nIndex) const;

   
public:
       
bool Empty();
       
size_t Size() const;
       
void SetSize(size_t nSize);

   
public:
       
void Insert(const Iterator &itBeforeWhich, const ValueType &tValue);
       
void Insert(const ReverseIterator &itBeforeWhich, const ValueType &tValue);
       
void PushFront(const ValueType &tValue);
       
void PushBack(const ValueType &tValue);
       
template <typename IteratorType>
       
void Insert(const Iterator &itBeforeWhich, const IteratorType &itFirstToInsert, const IteratorType &itAfterLastToInsert);
       
template <typename IteratorType>
       
void Insert(const ReverseIterator &itBeforeWhich, const IteratorType &itFirstToInsert, const IteratorType &itAfterLastToInsert);
       
Iterator Delete(const Iterator &itWhich);
       
ReverseIterator Delete(const ReverseIterator &itWhich);
       
void PopFront();
       
void PopBack();
       
Iterator Delete(const Iterator &itFirstToInsert, const Iterator &itAfterLastToDelete);
       
Iterator Delete(const ReverseIterator &itFirstToInsert, const ReverseIterator &itAfterLastToDelete);
       
void Clear();
       
void SetValue(const Iterator &itWhich, const ValueType &tValue);
       
void SetValue(const ReverseIterator &itWhich, const ValueType &tValue);
       
void SetValue(const Iterator &itFirstToSet, const Iterator &itAfterLastToSet, const ValueType &tValue);
       
void SetValue(const ReverseIterator &itFirstToSet, const ReverseIterator &itAfterLastToSet, const ValueType &tValue);

   
private:
       
ValueType *m_pData;
       
size_t m_nSize;
       
size_t m_nStart;
       
size_t m_nEof;

   
private:
       
void Release();
       
size_t GetWellSize(size_t nSize) const;
       
void MoveData(size_t nIndex, size_t nCount, int nDistance);
       
void CopyData(size_t nIndex, size_t nCount, ValueType *pNewMem) const;

    };
}

主要的考慮,還是想實現(xiàn)“跨容器的 iterator”(抱歉,我還是覺得這么稱呼挺符合我的預(yù)期的)。只是,在沒有語言層面的 concepts 支持的情況下,如何顯式地讓用戶知道模板參數(shù)要符合哪些條件呢?

在這里再次感謝一下 OwnWaterloo 同學(xué),上篇評論里的東西我會繼續(xù)慢慢琢磨的。^_^

posted on 2009-09-28 23:13 溪流 閱讀(771) 評論(18)  編輯 收藏 引用 所屬分類: C++

評論:
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 00:28 | OwnWaterloo
顯示讓用戶知道么……
有約定俗成
再不成就文檔
再不成…… 只能看源代碼了……

好消息是, 違反concepts一般都錯在編譯時,不會將錯誤留在運行時……
  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 09:32 | 溪流
@OwnWaterloo

如果有個 template <T> where T is IIterator,用戶看接口定義就知道該怎么做了;可是現(xiàn)在,只能到調(diào)用 Iterator 的某個具體方法的時候才報錯,用戶理解這個錯誤,就要理解我的實現(xiàn)了。這不僅增加了學(xué)習(xí)代價,還在一定程度上違背了封裝的初衷,不是么?一點變通的辦法都沒有嗎?
  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 15:55 | 陳梓瀚(vczh)
如果你對效率要求不是跟人家開發(fā)SqlServer的后臺一樣高的話,那就來一個虛基類吧,當成C#的interface用用。虛基類的作用主要在于你可以用他搞類型計算,譬如說來一個iterator你就可以知道它的element type是什么,而不用跟stl里面的一樣要求你必須在iterator的里面typedef。而且你還可以做很多iterator<A>到iterator<B>的轉(zhuǎn)換,從map<a,b>到iterator<pair<a,b>>的轉(zhuǎn)換等等。就是慢一點點罷了(真的是一點點)。  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 15:56 | 陳梓瀚(vczh)
@OwnWaterloo
壞消息是,那些編譯錯誤根本看不懂。  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 15:56 | 陳梓瀚(vczh)
@陳梓瀚(vczh)
我寫了一個錯誤的iterator然后錯誤消息竟然是list<T>里面的哪個代碼用了一個不存在的函數(shù)  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 16:09 | 陳梓瀚(vczh)
@溪流
template<typename T>
class IEnumerator
{
public:
virtual int Index()const=0;
virtual const T& Current()const=0;
virtual bool MoveNext()const=0;
virtual void Reset()const=0;
virtual bool Available()const=0;
virtual IEnumerator<T>* Clone()const=0;
};

template<typename T>
class IEnumerable
{
public:
virtual IEnumerator<T>* CreateEnumerator()const=0;
};

//注意使用方法
void MyCopy(List<int>& dest, const IEnumerable<int>& source)
{
....
}  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 16:14 | 陳梓瀚(vczh)
@溪流
而且我認為作為一個iterator,我絕對不會想到是Array.SetValue來通過它修改自己的值的  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 18:33 | 溪流
@陳梓瀚(vczh)

virtual IEnumerator<T>* CreateEnumerator()const=0;

這個,到使用的時候:
IEnumerator<T>* p = CreateEnumerator();
然后求用戶去 delete 嗎?  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 18:33 | 溪流
@陳梓瀚(vczh)

嗯……iterator 一般有哪些約定成俗的規(guī)則?  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 18:35 | 溪流
@陳梓瀚(vczh)

我覺得,出現(xiàn)在具體實現(xiàn)上的編譯錯誤,本不應(yīng)該留給用戶的。最好是在類型檢查的時候就能報錯。  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 20:23 | OwnWaterloo
OO為什么被人吹捧?
可以說, 是它開創(chuàng)了一個歷史,人們開始普遍采用 "對抽象的、多態(tài)的事物編程"。
 
在那之前, 無論是OP還是OB, 都只能完成模塊化, 方便分工開發(fā)與測試。很少使用多態(tài)技術(shù)。

OB編程(OP就省了…… OP->OB依然能完成一定復(fù)用,但方式不同):
void f_ob(T v) { v.f(); }
 
f是針對一個具體的T進行編程。
f的行為和T的行為緊緊綁定在一起。
f想要表現(xiàn)出不同行為, 必須要T表現(xiàn)出不同行為。
但無論T如何改變,T和f都只具有一種行為,最后一次改變后具有的行為。
 

OO編程:

void f_oo(I& i) { i.f(); }
 
f現(xiàn)在的行為, 僅僅與i所表現(xiàn)出的契約綁定在一起。
而i可以有各種各樣的滿足契約的方式。
這樣的一大好處就是, 對不同的D : I, f可以被復(fù)用。
得到這一好處的前提就是, D 滿足 I與f之間的契約。
 

GP編程:
template<typename T>
void f_gp(T v) { v.f(); }
 
同樣提供了多態(tài)行為:以不同的T帶入f, 就能得到不同的行為。
使得f能被復(fù)用。STL中的組件, 大部分是通過這種方式被復(fù)用的。
并且,STL組件之間, 也大部分是通過這種方式復(fù)用的。
 

1.
無論是GP還是OOP都是組合組件的方式。
它們(典型地)通過concepts 和 interface來抽象出組件多態(tài)行為。
對這種抽象事物編程得到的結(jié)果(函數(shù)/類模板,包),可以被復(fù)用(軟件工程一大目標)。
-------- -------- -------- -------- -------- -------- -------- --------
 

上面提到契約。
無論是OP、OB、OO、GP, 組件間要能協(xié)同工作, 都是需要契約的。
 
OP:
free 可以接受空指針, 而printf 不行。
前者是free對調(diào)用者定下的約束, 后者也是printf對調(diào)用者定下的約束
—— 要使用我就必須這樣做。
 
malloc 失敗返回空指針, 而new 拋異常, 否則返回可用動態(tài)內(nèi)存。
這是它們對調(diào)用者的承諾。
—— 使用我, 你能得到什么。

T* p = new T;
if (!p)  這種代碼只在古董編譯器上才可能有意義。
 
"加上NULL判斷更好" , 也只有"C++方言"的古董學(xué)者才說得出來。
 
new[] 要 delete[] , new 要 delete, 這也是契約。
"因為char是基礎(chǔ)類型,所以可以new[] , delete", 只有不懂軟件契約的白癡學(xué)者才說得出來。
 

OB:
要將CString s 轉(zhuǎn)換為 TCHAR*, 一定要用 s.GetBuffer  而不是 (TCHAR*)&s[0]
CString 的約束。
 
basic_string.c_str() 一定以'\0'結(jié)尾, 而data() 則不是。
basic_string  的承諾。
 

OOP:
我用的OOP庫、框架不多……  舉不出什么例子。
但它的契約和通常OB"非常類似" : 完成什么、需要調(diào)用什么、調(diào)用順序、 參數(shù)合法性。
 

GP:
GP總共有哪些契約形式, 我總結(jié)不出來。
但至少有一條 —— 它不再對T有完全限定, 而只作最小限定。
 

還是上面的代碼:
void f_oo(I& i ) { i.f(); }
D d;
f(d); // 要求 D : I

template<typename T>
void f_gp(T v) { v.f(); }
要求  v.f(); 合乎語法 :比如, 它既可以是non-static member function, 也可以是static member function。
并且僅僅要求這一點。
 
 
2.
契約是普遍存在的, 不僅僅是GP、 其他范式都有。
它是合作與復(fù)用的前提。
-------- -------- -------- -------- -------- -------- -------- --------
 
 
3.
為什么GP飽受爭議, 而OO沒有?
我覺得, 是因為從OB到OO過度比較自然
 
 
要求一個I需要怎樣, 一個I需要使用者怎樣的時候,
通常也會有類似的需求 —— 要求一個C怎樣, 一個C需要使用者怎樣。
注意, 這只是 client 與 I, 以及 client 與 C之間的契約。
在這個層面上, 不需要學(xué)習(xí)新的思想。
而下面會提到OO引入的新的契約形式。
 

而GP的契約形式, 都是一些全新的形式。
其中最主要的形式是: T 是否具有一個叫f的函數(shù)(操作符也可以理解為一種調(diào)用函數(shù)的方式)。
在C++中, 還有必須有某個名字的嵌套類型, 通過T::f強制static member function等形式。

OO比較流行、支持OO的語言比較多,是目前主流。
C++,Java,C#的開發(fā)者總共占了多少比例?
 
GP支持的語言其實也多。
但拋開C++(或者算上C++用戶中理解GP的人)怎么都比不上上面3個巨頭。
 

批評自己不熟悉的事物是不嚴謹?shù)摹?br>遇見STL編譯錯誤, 要么就去學(xué)習(xí)GP的方式, 要么就拋棄STL。
抱怨STL是種傻逼行為 —— 明明是自己不會用, 要怪只能怪自己。
 
 
-------- -------- -------- -------- -------- -------- -------- --------
4.
如同GP、 OO同樣需要學(xué)習(xí)、 需要文檔、 否則會充滿陷阱。
 
上面提到的client 與 I的契約形式通常和 clinet 與 C之間的形式相同。
使得OO的一個方面可以"溫固"。
 
而client 與 D之間的契約? 這個層面不"知新"是不行的。
并且這個層面上的契約常常是出bug的地方 —— 因為這是語法檢查不了的, 必須有程序員自己去滿足語意。
 
舉個例子 :
看見一個虛函數(shù),它是否可以被覆蓋? 覆蓋它的實現(xiàn)是否需要同時調(diào)用基類實現(xiàn)?
除非是約定俗成的一些情況, 比如 OnNotify、OnXXXEvent這種名字比較明顯。
其他情況, 不去看文檔, 依然是不知道的。
 
 
我剛剛就犯了一個錯。
python 中 繼承HTMLParser , 覆蓋__init__ 時, 必須調(diào)用基類實現(xiàn)。
我確實不知道構(gòu)造函數(shù)也可以被完全覆蓋……(原諒我…… 第1次使用python……)
在C++中, 基類的構(gòu)造函數(shù)是無論如何都會被調(diào)用的。
 
 
我沒有調(diào)用基類的__init__, 然后報了一個錯。
好在報錯清晰, 源代碼的位置都有, 源代碼也可見, 源代碼也清晰。問題很容易就找出來了。
 
 
如果
4.1.
它不是構(gòu)造函數(shù), 只是一個普通的虛函數(shù)?
名字也看不出什么蹊蹺?
 
4.2.
文檔也沒有記載是否需要調(diào)用基類?
(HTMLParser中的文檔沒有說要調(diào)用__init__, 這應(yīng)該是python的慣例, 所以就沒有記載了)
沒有嚴格的錯誤檢查?
沒有完整的、信息豐富的call stack trace?
等發(fā)現(xiàn)錯誤時, 也許都離題萬里了。
 
4.3.
沒有清晰的源代碼(其實到了要查看源代碼的時候, 已經(jīng)是……)?
 

這些問題在OO中同樣是存在的, 只是它沒引起編譯錯誤, 或者說編譯錯誤比較明顯, 容易修改。
而更多的語意檢查, OO中 client 與 D之間的層次, 依然要靠程序員的學(xué)識 —— 主要是查閱文檔的習(xí)慣。

對比GP
4.1之前的4.0(OnNotify, OnXXXEvent之流), 同樣存在一些約定俗成。
 
對4.1, 同樣是查文檔。
 
對4.2, 沒有文檔同樣犯錯。
C++中, 一部分錯誤可以提前到編譯時(C++只在持編譯時支持ducking type)
 
對4.3
同樣需要去查看源代碼。
 
GP的代碼比OOP難看? 
同上面, 只是因為不熟悉、不信任、不需要這種抽象方法, 這些契約的形式。
 

STL中的契約形式其實并不多。
[first,last) 左閉右開區(qū)間;
iterator的幾個種類;
(adaptable)binary(unary)_function;boost只是將其提升到N-nary,還省去了adaptable的概念;
相等、等價、嚴格弱序。
多嗎?
 
而且, 我不覺得為了比較要去實現(xiàn)一個IComparable 有何美感可言……
 
 
-------- -------- -------- -------- -------- -------- -------- --------
5. 這些新的契約形式、 抽象方式, 有沒有其優(yōu)勢?
當然有 —— 最小依賴帶來的靈活性
上面也提到, GP只依賴于其需要的契約, 對其不需要的, 通通不關(guān)心。
 
 
現(xiàn)在詳細解釋上面
D d;
f_oop(d); // D : I
 
T v;
f_gp(v);    // v.f
 
為什么后者比前者靈活。因為后者只依賴所需要的東西。
 
5.1
template<typename T>
void f123_gp(T v) { v.f1(); v.f2(); v.f3(); }
 
可以使用
struct T123_1 { void f1(); void f2(); void f3(); }
struct T123_2 { void f1(); void f2(); void f3(); }
 

void f123_oop(I& i) { i.f1(); i.f2(); i.f3(); }
必須有一個
struct I { virtual void f1(); virtual void f2(); virtual void f3(); };
然后是:
D1 : I; D2 : I; ...
 
 
5.2
如果現(xiàn)在需要實現(xiàn)另一個函數(shù), 它對T的需求更少 :

template<typename T>
void f12_gp(T v) { v.f1(); v.f2(); }

T123_1, T123_2 可以使用
 
新增一個:
struct T12_1 { void f1(); void f2(); }
依然可以使用
 

OOP就必須重構(gòu)了:

struct I12 { virtual void f1(); virtual void f2(); };
struct I123 : I12 { virtual void f3(); }
struct D12 : I12 {};
 
5.3
再看 :
template<typename T>
void f23_gp(T v) { v.f2(); v.f3(); }

T123_1, T123_2 依然可以使用
T12_1 不行。
 
但新增的
struct T23_1 { void f2(); void f3(); }; 可以使用
 
 
OOP又必須重構(gòu):
總體趨勢是這樣的, OOP需要極端靈活的時候, 就會變成這樣:
一個接口, 一個函數(shù)。
struct I1 { virutal void f1(); };
struct I2 { virutal void f2(); };
struct I3 { virutal void f3(); };
現(xiàn)在接口設(shè)計是極端靈活了。

但使用接口時, 依然逃不過2種都不太優(yōu)雅的作法:
1. 接口組合
struct I12 : I1, I2;
struct I23 : I2, I3;
struct I31 : I3, I1;

2. 接口查詢
不組合出那些中間接口, 但運行時作接口查詢:
void f12(I1* i1) {
  i1->f1();
  if (I2* i2 = dynamic_cast<I2*>(i1) {
     i2->f2();
  }
  else { 將一部分編譯時錯誤留到了運行時。 }
}
這不是故意找茬, 而是將STL中的iterator換個簡單的形式來說明而已。
 

也許絕大部分情況下, 是不需要靈活到每個接口一個函數(shù), 而是一個接口3、4個相關(guān)的函數(shù)。通常它們會被一起使用。

即使沒有上面如此極端, 假設(shè)IPerfect1、IPerfect2都是設(shè)計得十分合理的, 3、4個函數(shù)的接口, 通常這3、4個函數(shù)要么必須一起提供, 要么都不提供, 單獨提供是不符合語意的, 提供太多又是不夠靈活的。
這需要經(jīng)驗, 相當多的經(jīng)驗。 但總是可以完成的事情。
 
但組合接口, 依然是OOP的痛處。
我記不清C#和Java中的interface是否繼承自多個interface。
如果不行, 它們就可能需要運行時接口查詢。
而C++, 要在這種"組合接口"與接口查詢之前作一個選擇。
 
反觀GP, 它一開始就不是以接口為單位來提供抽象,而是按需而定
所以, 它既不需要仔細的拆分接口, 也不需要組合接口。
STL中數(shù)據(jù)、容器、算法相互無關(guān)、可任意組合。
應(yīng)該是前無古人的突破。
后面有沒有來者? 上面已經(jīng)說了, OOP要達到這種靈活性, 同樣也有其代價。
并且, OOP代價體現(xiàn)在丑陋, 而不是難以理解。
 

靈活的事物肯定比不那么靈活的事物難理解,抽象總比具體難理解。
所以抽象出一個合理的、廣泛接受的語意很重要。

* 就是解引用, ++ 就是前迭代, -- 就是后迭代。
支持--就是雙向, 支持 + n 就是隨機。
 
GP也不會胡亂發(fā)明一些語意不清晰的概念。
window w;
control c;
w += c; 這種代碼在GP界同樣是收到批評的。
 
 
最后, 軟件工程中, 是否真正需要靈活到如此程度, 以至于大部分人難以(或者不愿意去)理解的事物, 我就不知道了……
  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 22:16 | 溪流
@OwnWaterloo

讀了這么多文字,真是受益良多。

但必須指出的是,上面對于 OOP 和 GP 的某些比較是不公平的。在 OOP 中,只有你需要去繼承它的時候(即你需要修改這個類),你才需要了解源代碼,需要了解跟實現(xiàn)相關(guān)的“契約”。如果僅僅是使用的話,那么,給出全部 public class 的 public method 的聲明,應(yīng)該所有的使用者都不會犯語法錯誤,編譯器會提供完備的類型檢查。而同樣是使用(并不是去修改),GP 中,卻需要去了解它的實現(xiàn),這不是很不公平嗎?我們不是追求為了隱藏不必要的細節(jié),讓使用者減輕負擔(dān)嗎?當然,如果要去修改它,那么對它的實現(xiàn)是必須要了解的了。
  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-29 23:07 | OwnWaterloo
@溪流
嗯嗯, 你說得很對。

假設(shè)多態(tài)的使用者與多態(tài)抽象之間的層面叫A, 還有多態(tài)提供者與多態(tài)抽象之間的層面叫B。
OOP中的A和OB很相似, 只有B是新加的內(nèi)容。
而GP中, 無論A、B, 都是新鮮內(nèi)容。

所以這樣比較是不公平的~_~


我至今沒有完全明白rbtree的實現(xiàn), 但不妨礙我使用map和set。
對一般的內(nèi)建類型, 或者符合STL規(guī)范的值類型, 直接使用即可。
如果需要放自定義類型,需要了解的就是key_compare和嚴格弱序。
也不算多吧? OOP同樣離不開比較準則, 只是key_compare換成了ICompare。
如果還想高級一些, 還可以去了解allocator, 那是篇幅更長的一套規(guī)范。
OOP沒見有這功能, 不比較了。

boost中有一些庫, 我知道實現(xiàn)原理, 但不知道對付各種編譯器的trick。
還有一些隱約知道原理, 更多的是不知道。
boost的源代碼我一份都沒看過(堅持不下去…… 確實很丑陋, 但很多代碼都是為了對付不同編譯器而已)

舉個例子, any。 即使沒看源代碼, 我也知道這個庫應(yīng)該在何時使用, 以及如何使用 —— 因為我看了文檔…… 不多的。 interface也需要看文檔的吧?

但就是這么一個小東西, 使得我可以通過一個參數(shù)傳遞任何東西。
并且不再需要繼承自某個基類……

"一切皆為Object" —— 我覺得這是很可笑的事情。
Finder.find?
p1.fuck(p2); 還是 p2.fuck(p1);? 3p呢?
太可笑了……

而且在java和C#中實現(xiàn)free function其實并不難, 只是它們固執(zhí), 不愿意加入而已。

OOP根本就不是一種純粹的編程范式。 不結(jié)合其他范式, OOP根本就寫不出程序來。 不知道那些追求所謂"純OO"的家伙是怎么想的 ……
在我眼里, OO只有oo analysis, oo design, oo programming只是oo design而已。 實現(xiàn)design時, 是命令式的。
至少對java, c#的OO來說是如此。

不是我一人這么說, 你還可以去看看《冒號課堂》。


上面有點小錯誤, 糾正一下:
C/C++中本來就可以以單一參數(shù)傳遞任何東西……
any 是使得這一作法類型安全而已。
當然, 既然使用C/C++寫代碼, 不同與那些保姆語言, 程序員自己就要對類型安全負責(zé)。 所以any通常是為了堵住那些對類型安全尤為重視的人的嘴而已。
我還是更喜歡void* ...

真不知道那些成天叫囂著類型安全, 卻視generic加入java是一種退步, 使得java不純粹的人是怎么想的……
難道"不犯錯", 比"犯了錯總有人補救" 更重要?  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-30 00:04 | OwnWaterloo
上上面關(guān)于interface和concepts的比較, 是因前不久給一個項目經(jīng)理解釋ducking type和以函數(shù)為單位的抽象形式, 但沒成功……

現(xiàn)在算是想得比較清楚了, 但好像沒表達清楚…… 那么多文字, 我自己都不愿意看第2遍……


整理一下:

對單個"契約"的設(shè)計而言, 通過interface或是concepts沒有什么區(qū)別。
并且interface比concepts更廣為人知。
所以當時怎么都沒能說服他……

interface的劣勢(也就是concepts的優(yōu)勢)體現(xiàn)在"如何拆解與組合契約"上。
如何拆分,設(shè)計interface, 是門學(xué)問。
那幾個方法通常是應(yīng)該整體提供的?
這就是interface的劣勢的本質(zhì) —— 它總是要將若干方法"打包"到一起才可以。
極端情況, 只含有一個方法的interface也很常見, Dispose所屬接口就是。

interface更麻煩的地方在于組合。
當一個f需要若干種interface的功能時, 要么必須將一些interface繼續(xù)"打包", 形成一個新的, 要么運行時檢查。


而concepts打從一開始, 就僅僅依賴所需要的東西, 不需要"打包"這一過程。
拆分和組合是自由的。
從某種程度上來說, 這也容易造成晦澀的設(shè)計。
但什么設(shè)計不是學(xué)問呢…… interface的設(shè)計同樣需要經(jīng)驗。


concepts相比interface來說, 限制更少, 也更靈活。
這種靈活性是本質(zhì)上的 —— 因為不存在"打包"這一限制 ——是不以現(xiàn)實編程中是否需要這種程度的靈活性,以及這種靈活性是否會被人們普遍接受而轉(zhuǎn)移的。


靈活的事物通常難以掌握, 如果現(xiàn)實編程中不需要, 人們不理解、不接受, 也只能算是當前條件下的劣勢 —— 對太多數(shù)人來說晦澀、復(fù)雜, 無法被廣泛使用。
如果哪天人們接受了呢?



還有一點, 上面說的GP和OO、OOP概念太廣泛。 OO、OOP的定義到底是什么, 各有各的說法。
所以改為 concepts 和 interface( in java and C# )的比較, 比較準確。
并且某些其他支持OO的語言 —— 現(xiàn)在是個語言都要說自己支持OO, 不支持的也要改為支持... ——中, 是不需要interface這種"契約打包器"的。



樓主啊, 我自我感覺比較好的建議, 就只有建議你實現(xiàn)一套侵入式容器(包括樹式堆)而已, 既鍛煉了技巧, 又不陷入"重復(fù)發(fā)明輪子"。

其他的, 都是自說自話 …… 不必想太多-_-

因為做上這行了,沒什么時間總結(jié)平時的一些零散想法。
如果是中學(xué)做習(xí)題, 會因為做著做著, 就累了 …… 就轉(zhuǎn)而"總結(jié)一下吧,比單純做來得有效, 同時休息休息"。
而寫代碼…… 是沒有累的感覺的…… 就會一直寫下去……
只有在討論的時候, 才會想去總結(jié)一些東西。
把你的blog評論區(qū)當吐槽了…… sorry ...
  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-09-30 00:49 | 溪流
@OwnWaterloo

非常歡迎吐槽~哈哈
關(guān)于侵入式和非侵入式,說實話我也是前幾天第一次聽你說。我稍微查了下,不是很確切的了解其含義。前面我在 Iterator 里放了個 Array *m_pArray,后來拿掉了,改成放一個 ValueType *,有沒有改變侵入式/非侵入式方面的屬性呢?  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-10-01 14:16 | OwnWaterloo
@溪流
我out了……

boost 已經(jīng)有 intrusive 容器的實現(xiàn)了……
http://www.boost.org/doc/libs/1_35_0/doc/html/intrusive/intrusive_vs_nontrusive.html

我這里的boost版本非常老…… 1.33…… 所以沒發(fā)現(xiàn)……  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-10-12 18:39 | 陳梓瀚(vczh)
@OwnWaterloo
當然interface比起純GP還有一個好處,就是你可以對一個具體的類,譬如IEnumerable<int>得到類型推導(dǎo)結(jié)果int,但是你沒法對一個隨便什么object只是長得跟IEnumerator<int>一樣的東西來得到類型推導(dǎo)結(jié)果int。這(類型推導(dǎo))是GP更大的價值,可以跟OOP一起,OOP充當抽象,GP用來做推導(dǎo),能做出很多漂亮的用法來。譬如說:

MyList<int> list;(繼承自IEnumerator<int>)
list>>Where(某個函數(shù))的結(jié)果一定是IEnumerator<int>,編譯器推導(dǎo)了。

反而vector<int>也想要支持的話,你會發(fā)現(xiàn)所有的容器都要寫一遍……所以我只需要讓我的容器都支持IEnumerator<T>,然后GP對IEnumerator<T>進行類型推導(dǎo)即可,提供10個功能我只寫10個函數(shù)。如果是vector<int>+list<int>+queue<int>什么的,提供10個功能要寫10×n個函數(shù),n==容器數(shù)量。

當然這僅僅是對于【容器】而言的。至于你剛才討論的很多都是其他的東西,就不納入了。  回復(fù)  更多評論
  
# re: 算了,還是不 typedef 了,類型真煩 2009-10-12 19:15 | OwnWaterloo
@陳梓瀚(vczh)
需求是iterator類型推導(dǎo)iterator解引用后的類型?
嘿嘿,真的不能嗎?

#include <iterator>
MyIt it1,it2;
typename std::iterator_traits<MyIt>::value_type // 這就是你要的
v = *it1;

// 除此之外還有其他幾種類型信息。
typename std::iterator_traits<MyIt>::pointer p = &v;
typename std::iterator_traits<MyIt>::reference r = v;
typename std::iterator_traits<MyIt>::difference_type d
= std::distance(it1,it2);

typename std::iterator_traits<MyIt>::iterator_category tag;
tag決定了iterator能做什么。

algorithm中的所有需要iterator的算法,都和容器完全無關(guān)。
和iterator相關(guān)的類型信息都是這么取得的。
自然不存在M*N(M=算法的數(shù)量,N=容器的數(shù)量)的說法。
而是M(M=算法數(shù)量)。


給你舉個例子可能比較明顯:
需要value_type的算法我一時還想不出來……
來個其他的需要difference_type的意思意思:
template<typename InIt,typename T>
typename iterator_traits<InIt>:: difference_type // 返回類型
count(InIt first,InIt last,const T& v) {
typename iterator_traits<InIt>:: difference_type c = 0;
for (;first!=last; ++first) if (*first==v) ++c;
return c;
}



這是GP的類型推導(dǎo)方式 —— 嵌入類型。這用法漂亮嗎?


實現(xiàn)這一魔法的工作:
iterator_traits只需實現(xiàn)一次。
各個容器其實不需要做什么工作。
工作在每一個iterator類型上,它必須有這幾種嵌套類型。
當然,iterator頭文件中提供了std::iterator, 可以繼承自它而得到這幾種嵌套類型。
不過我一般喜歡自己寫,繼承可能會影響空基類優(yōu)化。
多嗎?


而且,有一點OOP是辦不到的。 所有的iterator都不需要有一個"基類"。
T arr[size];
&arr[0] 類型是T*, 是iterator,而且還是random_access。但是它的基類應(yīng)該是什么才好呢?
它只有4字節(jié)。OOP就那個vptr就4字節(jié)了,加點數(shù)據(jù)再加上padding,8字節(jié)至少。



"反而vector<int>也想要支持的話,你會發(fā)現(xiàn)所有的容器都要寫一遍……"
這是什么需求? 需要所有容器都寫一遍? 說出來看看?  回復(fù)  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲视频欧美在线| 最新日韩欧美| 美女任你摸久久| 欧美国产欧美亚洲国产日韩mv天天看完整 | 国产人成精品一区二区三| 99re国产精品| 亚洲欧美日韩国产中文| 国产精品一区二区久久久| 亚洲自拍16p| 噜噜噜91成人网| 最新日韩中文字幕| 欧美视频一区二区在线观看| 亚洲欧美另类国产| 久久天天躁狠狠躁夜夜av| 亚洲三级视频在线观看| 欧美日韩亚洲视频| 欧美制服丝袜第一页| 亚洲大片免费看| 亚洲视频网在线直播| 伊人久久亚洲热| 欧美日韩三区| 久久青青草综合| 夜夜爽av福利精品导航| 久久综合伊人77777| 一区二区三区国产盗摄| 国模私拍一区二区三区| 欧美色网一区二区| 久久久99精品免费观看不卡| 激情懂色av一区av二区av| 欧美人成网站| 久久黄金**| 一区二区三区黄色| 欧美电影在线观看完整版| 欧美亚洲一级| 99精品视频免费在线观看| 久久久爽爽爽美女图片| 亚洲视频在线观看三级| 欧美顶级少妇做爰| 久久人91精品久久久久久不卡 | 日韩亚洲视频| 狠狠色综合色综合网络| 欧美午夜精品久久久久久孕妇| 久久婷婷一区| 欧美一二三视频| 一区二区精品| 99ri日韩精品视频| 亚洲经典自拍| 欧美福利一区| 欧美成人在线网站| 欧美99在线视频观看| 久久久久五月天| 久久爱www| 欧美一区成人| 一本大道久久a久久综合婷婷| 精品av久久久久电影| 国产综合精品| 欲色影视综合吧| 精品成人在线观看| 在线成人小视频| 在线观看视频一区二区| 一区二区视频在线观看| 国产一区二区无遮挡| 国产欧美精品| 国内精品99| 亚洲国产精品99久久久久久久久| 一区二区三区在线观看国产| 国产在线成人| 亚洲欧洲一区二区三区| 亚洲欧洲在线一区| 正在播放欧美视频| 亚洲无毛电影| 久久久九九九九| 美女视频黄 久久| 欧美刺激性大交免费视频| 亚洲国产一二三| 一本色道久久综合亚洲精品不卡| 亚洲五月六月| 久久精品国产99| 久久久精品免费视频| 欧美久久婷婷综合色| 欧美色中文字幕| 亚洲砖区区免费| 正在播放欧美视频| 亚洲图中文字幕| 香蕉久久国产| 美女日韩在线中文字幕| 欧美日韩一二三区| 国语自产偷拍精品视频偷| 亚洲国产成人久久综合| 亚洲乱码国产乱码精品精98午夜| 这里只有精品在线播放| 香蕉成人伊视频在线观看| 久久资源av| 亚洲风情亚aⅴ在线发布| 亚洲精品一区二| 午夜宅男欧美| 欧美成人免费观看| 国产精品视频xxx| 亚洲日本激情| 欧美在线观看天堂一区二区三区| 可以免费看不卡的av网站| 亚洲国产综合在线看不卡| 国产精品99久久久久久人| 久久国产夜色精品鲁鲁99| 麻豆精品视频在线| 国产精品一区二区三区观看| 好吊色欧美一区二区三区四区| 亚洲免费高清| 久久国产欧美日韩精品| 亚洲激情亚洲| 久久av资源网站| 国产精品高清在线| 亚洲精品一区二区网址| 久久精品免费| 亚洲天堂成人在线视频| 亚洲私人影院| 久热这里只精品99re8久| 欧美欧美在线| 激情文学综合丁香| 亚洲午夜激情网页| 欧美二区不卡| 欧美一区综合| 国产精品成人午夜| 99精品欧美一区二区三区| 欧美xxx成人| 久久成人精品电影| 国产亚洲一级| 亚洲午夜国产成人av电影男同| 亚洲国产成人久久| 欧美一区成人| 国产精品久久久久久户外露出| 亚洲激情欧美| 久久亚洲高清| 欧美在线一级视频| 黑人巨大精品欧美一区二区| 午夜视频在线观看一区| 夜夜嗨av一区二区三区四区| 欧美成人免费全部观看天天性色| 国产自产精品| 国产麻豆精品久久一二三| 亚洲神马久久| 亚洲色诱最新| 欧美午夜精品电影| 亚洲欧美精品伊人久久| 亚洲欧洲精品一区二区三区 | 日韩亚洲欧美成人| 亚洲国产高清自拍| 欧美日韩精品二区第二页| 一区二区三区高清在线| 亚洲一区在线视频| 国产曰批免费观看久久久| 亚洲第一精品久久忘忧草社区| 欧美激情精品久久久久久黑人 | 亚洲欧洲一区| 夜夜嗨av色综合久久久综合网| 国产欧美韩国高清| 欧美ed2k| 国产精品二区在线观看| 麻豆久久久9性大片| 欧美国产精品久久| 香港成人在线视频| 欧美91大片| 亚洲欧美制服另类日韩| 久久综合狠狠综合久久激情| 亚洲毛片在线看| 亚洲视频观看| 伊人精品成人久久综合软件| 欧美国产亚洲精品久久久8v| 欧美激情无毛| 国产伦精品一区二区三区在线观看 | 亚洲伦理在线免费看| 亚洲美女视频在线观看| 国产欧美一区二区三区国产幕精品| 欧美一区二粉嫩精品国产一线天| 亚洲欧美日韩综合aⅴ视频| 国产一区二区成人久久免费影院| 久久久久综合一区二区三区| 中文在线资源观看视频网站免费不卡| 欧美日韩视频在线一区二区观看视频 | 免费日韩av电影| 美女黄毛**国产精品啪啪| 国产精品99久久久久久有的能看| 亚洲国产综合在线| 亚洲一区二区三区四区五区午夜| 黄色亚洲精品| 亚洲福利视频在线| 国产精品色网| 亚洲激情电影在线| 国内精品嫩模av私拍在线观看| 日韩视频欧美视频| 在线日韩成人| 亚洲一区二区高清| 亚洲黄色免费| 亚洲欧美久久久| 在线亚洲欧美| 久久躁狠狠躁夜夜爽| 亚洲一区二区在线播放| 免费一级欧美片在线播放| 久久国产精品免费一区| 欧美日韩另类一区|