2008年5月24日 星期六

C++0x Concept

C++ 引進了模版,比方說我要寫一個泛用的兩數取最大值函式

template<>
T Max( T a, T b ) { return (a > b) ? a : b; }


那麼不管是整數,浮點數還是什麼,都可以套用進這個模版。但是
不是所有類別都可以套用進去,至少要是個數字,寫個 Max<>( a, b )
一點意義都沒有,在編譯的時候 compiler 會吐一串複雜難懂的錯誤訊息
跟你抱怨這個

以這個例子來說,套用進來的類別必須要能做「大於」運算


所以 c++0x 引進新的 concept 觀念。我們可以寫一個 concept 規範
一個有「大於」運算的類別

concept HasLarger<>
{
bool operator>( T, T );
}


這樣就可以重寫上面的範例

template<> requires HasLarger<>
T Max( T a, T b ) { return (a > b) ? a : b; }


簡化的寫法

template<>
T Max( T a, T b ) { return (a > b) ? a : b; }


除了 concept,還有所謂的 concept_map


繼續用上面的例子說明,假設你真的很想用 Max<>( a, b )
這樣的函式。可以用 concept_map 告訴編譯器要怎麼處理這種特例

concept_map HasLarger<>
{
bool operator>( Camera& a, Camera& b) { return true; }
// 反正是範例, 假設永遠 a > b
}


這樣子使用
Camera a, b;
Camera& c = Max<>( a, b );
就不會有問題了


由於有 concept_map,有時候可以寫出怪怪的程式

concept HasAdd<>
{
T operator+( T, T );
}

concept_map HasAdd<>
{
int operator+( int a, int b ) { return a * b; }
}

template<>T Add( T a, T b ) { return a + b; }


這時候在程式中寫
int a = 3;
int b = 4;
int c = Add<>Add( a, b );
結果是 12


如果又突然不想要 concept_map,那麼可以這樣寫
int a = 3;
int b = 4;
late_check
{
int c = Add<>Add( a, b );
}
這樣結果是 7

沒有留言: