關注C++0x: Concept

來源:互聯網
上載者:User
  要說C++0x中對泛型編輯最大的改變,當屬Concept了。
Concept這個東西,其實並不是剛剛提出來的。可以說,Concept是STL的基礎。

STL之於C++的地位不言而寓,而其中最重要的,當屬迭代器(Iterator)的概念(Concept)了。這是接觸STL後得到的最明顯的Concept。有了迭代器,就可以將演算法與容易分離開來,這樣就奠定了STL的基礎。於是一個又一個服務於STL的概念(Concept)就誕生了。
不過相信大多數人只是直接使用STL,因此對於Concept沒有什麼印象。一旦涉及到自行建立程式庫,特別是建立相容於STL規範的容器或演算法的時候,就肯定要接觸到STL中的一堆Concept了。
舉個簡單的例子,如何?一個Iterator?STL中的Iterator有幾個類別:ForwardIterator、BidirectionalIterator、RandomAccessIterator等5類。現在需要實現一個用於vector容器的Iterator,顯然是要符合上述三種類型。但是要從STL找到象ForwardIterator的通用類,肯定是找不到。最多隻能找到一個Iterator的通用定義:template<class Category, class Type, class Distance = ptrdiff_t
   class Pointer = Type*, class Reference = Type&>
   struct iterator {
   typedef Category iterator_category;
   typedef Type value_type;
   typedef Distance difference_type;
   typedef Pointer pointer;
   typedef Reference reference;
   };

很昏倒吧,全是typedef。至於更具體的Concept,只好開啟C++的標準文檔了,想要滿足ForwardIterator要哪些需求,滿足RandomAccessIterator要哪些需求,然後對照著去實現。
至於實現後的Iterator是否真的符合這些Concept,就只好摸摸自已的良心,問問是否完全測試過了。
為什麼會這樣呢?因為這些Concept目前只停留在文檔中。C++編譯器對Concep完全沒有概念。更過份的是,C++編譯器甚至完全看不到或只看到一部份剛才定義的Iterator--因為大多數編譯器僅對確實需要具現化的類或成員才進行編譯。

比如:template<typename T>
class test
{
public:
    void kill_cpp(T t)
    {
        不要調用我啊!
    }
};
int main(int argc, char* argv[])
{
    test<int> t;
    //t.kill_cpp(0);
    return 0;
}

編譯就完全通過,C++編譯器對“不要調用我啊!”這幾個字視而不見。我有時候就利用這個特點,以保證某些函數確實不應該被調用,而一旦被誤調用了,還可以有一個能看得明白的錯誤資訊:error C2065: '不要調用我啊!': undeclared identifier  (VC2008 Beta2)

也許STL的Concept還比較少接觸。那麼在寫泛型程式時,也總會遇到一些類似的情形。比如下面的代碼:template<typename T>
static void Show(const T& t)
{
    cout << t.Message() << endl;
}

這個函數用於顯示某個類的資訊。顯然,它要求該類型必須擁有 Message 成員函數。但這個函數的使用者知道嗎?也許知道,因為你文檔寫的很詳細。可是一旦使用者忘記或者誤用了,那麻煩就出來了,肯定是一堆錯誤資訊。這個例子還比較簡單,也就多幾個錯誤資訊,稍微仔細查看,還是能夠解決問題。那麼下面的例子:#include <list>
#include <algorithm>
using namespace std;

int main(int argc, char* argv[])
{
    list<int> lst;
    sort(lst.begin(), lst.end());
    return 0;
}

這個例子將會產生一大堆的錯誤資訊,足以讓剛接觸到的人如墜雲霧。而實際原因只不過是list的iteraotr不是RandomAccessIterator(也就是說list不能象數組一樣隨機訪問,所以不能使用sort函數)。

Java和.NET等新加入泛型程式設計特性的語言,對此自然深有體會,不約而同都加入了模板約束的機制。假如讓.NET來實現這個sort的話,它可能會這麼寫:void sort<T>(T container) where T : IEnumerable
{
 
}

這樣,當container被代入共它類型,如int時,編譯時間將會給出明確的錯誤:The type 'int' cannot be used as type parameter 'T' in the generic type or method sort<T>(T)'.
There is no boxing conversion from 'int' to 'System.Collections.IEnumerable'. (VC# 2008 Beta2)

是啊,模板約束很有用,至少可以讓我們放心,編譯器會幫我們檢查那個T要滿足什麼條件。於是開始羨慕起Java和C#了:畢竟是後來者,把C++的優點採用了,缺點補上了...
為了讓C++也能擁有這個特性,C++的模板庫編寫者真的是費盡心思。類似模板元編程等技術橫空出世。boost有相當部份的程式類在為此努力。但是所有的努力,都僅僅只能讓程式庫的易用性有一些改善,卻大大增加了程式庫的編寫複雜度和可維護性。勢必在C++語言中內建相關的特性,才是最終的解決方案。

盼啊盼啊,終於盼來了C++0x,而且令人驚喜的是,C++並沒有採用Java和C#那一套模板約束的方式,而是將STL的Concept從文檔化變成語言特性了。這個變化我認為是革命性的,而且還帶來了前所未有的新的編程方式,將建立繼模板以來的新的流行--可以預見,C#和Java最終也將會採用這個特性。
Concept的應用程式套件含了C#和Java中的模板約束,但不止於此。模板約束僅僅是基本。

對於上面sort的例子,在C++0x中將會出現比較簡潔的錯誤資訊:sort.cpp: In function 'void f()':
sort.cpp:7: error: no matching function for call to 'sort(std::_List_iterator<int>, std::_List_iterator<int>)'
<path>: note: candidates are: void std::sort(_Iter, _Iter) [with _Iter = std::_List_iterator<int>] <where clause>
sort.cpp:7: note:   no concept map for requirement 'std::MutableRandomAccessIterator<std::_List_iterator<int> >'

錯誤資訊一條:找不到可用的sort函數。
提示資訊一條:List的Iterator沒有到MutableRandomAccessIterator的映射。
稍微動一下腦,也就明白sort是需要隨機訪問的Iterator,而List既沒有該類別的Iterator,也沒有可以到該類別的Iterator的映射。
解決方案有兩個:一是換用有隨機訪問的Iterator的容器,如vector;一是實現一個到MutableRandomAccessIterator的映射。

Concept目前在C++0x的提案已經確認肯定會被通過了。Concept引入C++,目的是要讓模板庫得容易使用,和容易編寫。

對Concept有興趣的朋友可以查看相關的文檔。也許因為C++0x眾多令人激動的特性,我會用我的方式進行一一表達。

相關連結:
http://del.icio.us/pongbablog/cplusplus
  《C++0x漫談》系列之:Concept, Concept!
  C++0x展望[語言核心進化]
呵呵,偷一下懶,劉未鵬的文章推薦對C++0x感興趣的朋友觀看,文後所附的資料及相關的標準提案相當詳細。這裡就不照抄了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.