国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設(shè)計 > 正文

C++之父Bjarne談C++的未來發(fā)展

2019-11-17 05:07:50
字體:
供稿:網(wǎng)友
    富有活力的語言需要不斷改變和成長,C++也不例外。在本文中,Bjarne Stroustrup提出了自己對C++的設(shè)計和演化的看法。

  為了讓編譯器、工具和類庫實現(xiàn)者跟上節(jié)奏,讓用戶吸收標準C++所支持的編程技術(shù),在早有預(yù)計的、沉寂了幾年之后,委員會再次考慮語言擴展問題了。"擴展工作組"已經(jīng)建立了,它代替了"演化工作組"。名稱的改變(這是Tom Plum的建議)反映了更重要的是語言特性和標準類庫工具的集成。我仍然是該工作組的主席。我希望這可以確保C++版本的連貫性和最終結(jié)果的一致性。相似的,委員會成員資格也顯示了大量人員和組織的連續(xù)參與。幸運的是,也出現(xiàn)了很多新的面孔,為委員會帶來了新的影響和新的專家意見。

  我們打算對語言本身的改變保持謹慎和保守,重點強調(diào)兼容性。主要的目的是把主要的努力引導到標準類庫的擴展上來。在標準類庫方面,我們的目標是大膽進取,利用一切機會。

  對于標準類庫,我希望根據(jù)類庫技術(shù)報告的要素來建立它,使它成為一個用于系統(tǒng)編程的更廣泛的平臺。例如,我希望看到用于某些領(lǐng)域的類庫,例如目錄/文件夾操作、線程和套接字。我還希望委員會同情很多新的C++程序員,提供類庫工具支持背景不同的新手(不是新程序員和C的難民)。例如,我希望看到一個使用范圍檢查STL的標準方法。我對最頻繁地被請求添加到標準類庫中的標準GUI(圖形用戶接口)的期望值很低。但是,奇跡有時候也會發(fā)生--記得STL嗎?

  對于語言本身,我希望重點強調(diào)支持泛型編程的特性,因為泛型編程是語言的使用取得最大進步的領(lǐng)域。此處,我將調(diào)查兩個要害部分:

  ·概念(Concepts):用于模板參數(shù)的類型系統(tǒng)

  ·初始化器(Initializer)列表:初始化工具的泛化

  與以往一樣,建議的數(shù)量仍然遠遠超出了委員會能夠處理和該語言能夠吸收的數(shù)量。請記住,接受所有好的建議是不可能辦到的。
該語言擴展以支持泛型編程的全部目標是為工具提供更大的一致性,答應(yīng)我們用泛型直接表示用于解決問題的類。

  我的其它優(yōu)先考慮(與更好地支持泛型編程一起)是更好地支持初學者。目前的建議有一種值得注重的傾向,即這些建議照顧了哪些提出和評估建議的專家用戶。有些簡單地幫助那些新手的建議經(jīng)常被忽略了。我認為這是一種潛在的致命的設(shè)計偏好。除非新手受到了充分的支持,否則只有很少人能夠成為專家。此外,很多人并不希望成為專家;他們希望仍然是"偶然的C++用戶"。例如使用C++進行物理計算或控制試驗設(shè)備的物理學家只有有限的學習編程技術(shù)的時間。計算機專家可能會在編程技術(shù)方面花費很多時間,而不僅僅是期望。我們必須消除那些采用優(yōu)良技術(shù)的不必要的障礙。

  一個非常簡單的例子如下:

vector<vector<double>> v;
  在98年的C++中,這會導致語法錯誤,因為>>是一個單獨的詞匯記號,而不是封閉模板參數(shù)列表的兩個>。V正確的聲明可能是:

vector< vector<double> > v;
  我把它看作是一種阻礙。我曾經(jīng)建議這個問題值得解決,但是當前的規(guī)則和演化工作組用一些很好的理由兩次拒絕了我的建議。但是,這些理由都是語言技術(shù)方面的,而新手(包括其他語言的專家)沒有愛好。不接受第一種(也是十分)明顯的v聲明浪費了用戶和教師的時間。我希望>>問題和其它相似的"阻礙"不要再出現(xiàn)在C++0x中。實際上,我與Francis Glassborow和其他人一起,正在試圖系統(tǒng)地消除最頻繁發(fā)生的這類"阻礙"。      另一個"阻礙"是:使用默認的復制操作(構(gòu)造或賦值)來復制帶有用戶自定義析構(gòu)函數(shù)的類對象是合法的。在這種情況下,要求用戶自定義的復制操作將消除大量的、與資源治理相關(guān)的麻煩錯誤。例如,考慮下面這個過度簡單化的字符串類:

class String {
  public:
   String(char* pp) :sz(strlen(pp)), p(new char[sz+1]) { strcpy(p,pp); }
   ~String() { delete[] p; }
   char& Operator[](int i) { return p[i]; }
  PRivate:
   int sz;
   char* p;
};
void f(char* x)
{
  String s1(x);
  String s2 = s1;
}

  在構(gòu)造s2之后,s1.p 和 s2.p指向相同的內(nèi)存區(qū)域,而這塊內(nèi)存被刪除了兩次,可能導致災(zāi)難性的后果。這個問題對于經(jīng)驗豐富的C++程序員來說是很明顯的,他們一般會提供適當?shù)膹椭撇僮骰蚪箯椭啤5牵@個問題會嚴重地困擾新手,破壞其對語言的信任。

  禁止帶有指針成員的類對象的默認復制行為可能更好,但是這會導致令人厭煩的兼容性問題。修補長期存在的問題的難度比表面看起來要復雜很多,非凡是在考慮C兼容性的時候。

  1、概念(Concepts)

  D&E(編者注:"C++的設(shè)計和演化"通常簡稱為D&E)關(guān)于模板的討論中包含的關(guān)于模板參數(shù)的約束問題就占用了整整三頁。很明顯,我覺得應(yīng)該需要一個更好的解決方案。在使用模板(例如標準類庫的算法)的過程中出現(xiàn)的微小錯誤所導致的錯誤消息可能非常長,并且沒有對我們沒有任何幫助。這個問題是由于模板代碼絕對相信自己的模板參數(shù)。看看下面的find_if():

template<class In, class Pred>
In find_if(In first, In last, Pred pred)
{
  while (first!=last && !pred(*first)) ++first;
  return first;
}

  在上面的代碼中,我們對In和Predicate類型作出了很多假設(shè)。從代碼中我們可以看出,不知什么緣故,In必須用適當?shù)恼Z義支持!=、* 和++,并且我們必須能夠把In對象復制為參數(shù)和返回值。類似的,我們可以看到,我們可以調(diào)用一個Pred,其參數(shù)是從In返回的任何類型的*(取值操作符),并給結(jié)果應(yīng)用了!操作符,這個結(jié)果可以被當作是布爾型的。但是,在代碼中所有的這些都是隱含的。標準類庫仔細地記載轉(zhuǎn)發(fā)迭代子(例子中的In)和謂詞(Pred)的這些需求,但是編譯器是不會閱讀手冊的。試試下面的錯誤,看你的編譯器顯示的錯誤信息:

find_if(1,5,3.14); // 錯誤
  不完整的、但是十分高效的,以我的舊想法--讓構(gòu)造函數(shù)檢查模板參數(shù)的假設(shè)條件--為基礎(chǔ)的解決方案現(xiàn)在已經(jīng)廣泛使用了。例如:

template<class T> strUCt Forward_iterator {
static void constraints(T a) {
++a; a++; // 可以增加
T b = a; b = a; // 可以復制
*b = *a; // 可以廢棄和復制結(jié)果
}
Forward_iterator() { void (*p)(T) = constraints; }
};

  上面的代碼定義了一個類,只有當T是一個轉(zhuǎn)發(fā)迭代子的時候,它才能編譯。但是,F(xiàn)orward_iterator對象沒有做任何實際的事務(wù),因此編譯器只能(并且的確是)對這種對象做微乎其微的優(yōu)化操作。我們可以在如下所示的定義中使用Forward_iterator:

template<class In, class Pred>
In find_if(In first, In last, Pred pred)
{
  Forward_iterator<In>(); // 檢查模板參數(shù)類型
  while (first!=last && !pred(*first)) ++first;
   return first;
}

  Alex Stepanov和Jeremy Siek做了很多工作來開發(fā)和普及這種技術(shù)。他們使用這種技術(shù)的一個地方是Boost類庫,但是目前你會在大多數(shù)標準類庫實現(xiàn)中發(fā)現(xiàn)約束類。在錯誤消息的質(zhì)量方面,它們的差異是很大的。

  但是約束類最多是一個不完整的解決方案。例如,在定義中進行測試--假如檢查工作只能在聲明中完成,那么就會好很多。使用這種方式的時候,我們必須遵循接口的使用規(guī)則,并且可以開始考慮真正的模板分開編譯的可能性問題。

  因此,讓我們告訴編譯器我們所期望的模板參數(shù):

template<Forward_iterator In, Predicate Pred>
In find_if(In first, In last, Pred pred);

  假設(shè)我們能夠表示出Forward_iterator和Predicate是什么,那么編譯器現(xiàn)在可以不理會它的定義,單獨地檢查find_if()調(diào)用了。這時我們所需要做的工作是為模板參數(shù)建立一個類型系統(tǒng)。在現(xiàn)代C++環(huán)境中,這種"類型的類型(types of types)"被稱為"概念(concepts)"。我們可以通過很多途徑來說明這種概念;從現(xiàn)在開始,把它們想作是直接受到語言支持的、擁有更好的語法的約束類。一個概念說明了某種類型必須提供的什么工具,而不是說明它如何提供這些工具。完美的概念(例如<Forward_iterator In>)與數(shù)學抽象("對于所有的類型In,In可以被增加、銷毀和復制")非常類似,如同最初的<class T>就是數(shù)學上的"對于所有的類型T"。

  只要給出了find_if()的這種聲明(并且不是定義)之后,我們就可以編寫

int x = find_if(1,2,Less_than<int>(7));
  這個調(diào)用會失敗,因為int不支持*。換句話說,這個調(diào)用在編譯時會失敗,因為int不是一個Forward_iterator。重要的是,它使得編譯器輕易報告用戶語言中的錯誤,并且在編譯時,調(diào)用會被首先看到。

  不幸的是,知道迭代子參數(shù)是Forward_iterator并且謂詞參數(shù)是Predicate也不足以保證find_if()調(diào)用成功編譯。這兩個參數(shù)是互相影響的。非凡是謂詞的參數(shù)是一個使用*(pred(*first))解除引用的迭代子。我們的目的是在與調(diào)用分離的情況下,完善模板的檢測,同時在不查看模板定義的情況下,完善每個調(diào)用的檢查,因此概念必須有充分的表現(xiàn)能力,能夠處理模板參數(shù)之中的這類迭代子。一種辦法是用平行的參數(shù)來表示概念,這與模板的參數(shù)化方式類似。例如:

template<Value_type T,
Forward_iterator<T> In, // 迭代子在T序列中
Predicate<bool,T> Pred> // 帶有 T 參數(shù)并返回一個布爾值
In find_if(In first, In last, Pred pred);

  在上面的代碼中,我們要求Forward_iterator必須指向類型T的元素,它也是Predicate的參數(shù)類型。      通過普通參數(shù)(此處是參數(shù)T)來表達模板參數(shù)之間必要的關(guān)系,很不幸沒有強大的表現(xiàn)能力,導致我們添加模板參數(shù),并且間接地(無法直接地)表達需求。例如,上面的例子不能說明把*first的結(jié)果作為參數(shù)傳遞給pred一定可行。
其實,它說明的是Forward_iterator和Predicate共享了一個模板參數(shù)類型。為了處理這類問題,我們正在研究直接表達模板參數(shù)之間關(guān)系的可能性。例如:

template<Forward_iterator In, Predicate Pred>
where (assignable<In::value_type, Pred::argument_type>)
In find_if(In first, In last, Pred pred);

  這種方法也有自己的問題,例如它的要求(where子句)趨向于增加模板定義本身的復雜性,并且流行的迭代子(例如int*)并不擁有成員類型(例如value_type)。

  概念的一種可能的表達方式是直接支持我們過去使用的約束類這種表達方式。例如,我們采用如下的方式來定義前面例子中使用的Forward_iterator:

template <class T> concept Forward_iterator {
  // 參數(shù)化的概念
  Forward_iterator a;
  ++a; a++; // 可以增加
  Forward_iterator b = a; b = a; // 可以復制
  *b = *a; // 可以廢除和復制結(jié)果
  T x = *a; *a = x; // 可以認為結(jié)果是T類型的
};

  或者

concept Forward_iterator { // 概念沒有用參數(shù)表示
Forward_iterator a;
++a; a++; //可以增加
Forward_iterator b = a; b = a; //可以復制
*b = *a; // 可以廢除和復制結(jié)果
};

  參數(shù)化的概念定義可用于find_if的第一種聲明,不帶參數(shù)的用于第二種。它們表現(xiàn)了可替換使用的語言設(shè)計。我們在這個領(lǐng)域還會提供一些設(shè)計選擇。但是,看看下面的情形:

int x = find_if(1,2,Less_than<int>(7));
  這是不合格的,因為1和2是int型的,而int不支持*。假如我們使用參數(shù)化的概念設(shè)計,它也是不合格的,因為int不是一個能夠與Forward_iterator<T>匹配的參數(shù)化類型。另一方面,看下面的例子:

void f(vector<int>& v, int* p, int n)
{
vector<int>::iterator q = find_if(v.begin(),v.end(),Less_than<int>(7));
int* q2 = find_if(p,p+n,Less_than<int>(7));
// …
}

  很明顯,我是在報告目前正在進行的工作,但是某種形式的概念成為C++0x的基石是很可能的。模板已經(jīng)成為多數(shù)有效的(和高效的)C++編程樣式的要素,但是它遭受很多困擾:大量的、無用的錯誤消息,缺乏基于模板參數(shù)重載模板的工具,分開編譯很差。概念直接解決了所有這些問題,同時還沒有基于方法的抽象基類的主要缺陷--通過虛擬函數(shù)調(diào)用的運行時解析的性能開銷。重要的是,概念不依靠于顯式聲明的子類型層次,因此不需要邏輯冗余的層次關(guān)系,并且可以認為內(nèi)建類型與類是平等的。

  現(xiàn)在以概念和它與其它語言中相似的構(gòu)造之間可能的關(guān)系為主題的論文很廣泛。Matt Austern、Jaako J?rvi、Mich Marcus、Gabriel Dos Reis、Jeremy Siek、Alex Stepanov和我都活躍在這個設(shè)計問題的領(lǐng)域。

  2、泛化的初始化器

  C++的一個基本的想法是"對用戶定義類型的支持如同內(nèi)建類型一樣好"。但是,看看下面的情形:

double vd[ ] = { 1.2, 2.3, 3.4, 4.5, 5.6 };
vector<double> v(vd, vd+5);

  我們可以直接使用初始化器列表來初始化該數(shù)組,然而對vector來說,我們做得最好(指壞處最少)的方式就是建立一個數(shù)組并用該數(shù)組來初始化vector。假如只有少量幾個初始化器值,我甚至于可能使用下面的方式來避免明確地說明初始化器值的數(shù)量(在上面的例子中是 5):

vector<double> v;
v.push_back(1.2);
v.push_back(2.3);
v.push_back(3.4);
v.push_back(4.5);
v.push_back(5.6);

  我認為誰也無法適當?shù)卣{(diào)用上面的任何解決方案。為了得到最輕易維護的代碼,并且不讓內(nèi)建(并且是天生危險的)數(shù)組受到的"寵愛"比推薦的用戶定義類型多vector,我們可以編寫下面的代碼:

vector<double> v = { 1.2, 2.3, 3.4, 4.5, 5.6 };
  或者

vector<double> v ({ 1.2, 2.3, 3.4, 4.5, 5.6 });
  由于參數(shù)傳遞是在初始化過程中定義的,因此對于帶有vector的函數(shù)來說,這也是可行的:

void f(const vector<double>& r);
// …
f({ 1.2, 2.3, 3.4, 4.5, 5.6 });

  我相信這種初始化器的泛化會成為C++0x的一部分。
它將成為構(gòu)造函數(shù)檢查工作的一部分,因為人們發(fā)現(xiàn)的很多缺陷都似乎可以通過構(gòu)造函數(shù)的泛化(例如轉(zhuǎn)發(fā)構(gòu)造函數(shù)、有保障的編譯期構(gòu)造函數(shù)、繼續(xù)的構(gòu)造函數(shù))來解決。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 合山市| 太谷县| 库车县| 齐河县| 嘉峪关市| 普宁市| 镇安县| 桦甸市| 无为县| 峡江县| 方正县| 车致| 英吉沙县| 丰县| 拉孜县| 横山县| 大余县| 凤山市| 信丰县| 常宁市| 车险| 邢台县| 古丈县| 神木县| 甘德县| 涿州市| 高阳县| 东宁县| 巴中市| 南溪县| 合川市| 江安县| 监利县| 绥中县| 湘潭县| 碌曲县| 光山县| 凌海市| 马边| 建湖县| 临清市|