Tuples Herb Sutter(陶章志譯) (轉)

worldblog發表於2008-01-31
Tuples Herb Sutter(陶章志譯) (轉)[@more@] 

Tuples

Herb Sutter(陶章志譯)

就像我上期所報導的一樣,在2002十月標準會議上,兩個庫擴充套件作為標準庫延深,而被透過。:namespace prefix = o ns = "urn:schemas--com::office" />

1  是Doug Gregor’s提出的多型的 wrappers。

2  Jaakko Järvi's提出的tuple型別。

這兩個都是直接來在Boost專案。(Boost專案是一個C++ libraries 集合)上次,我答應在這期和下一期將介紹這兩個擴充套件的庫,這個月,就讓我來簡單的介紹一下tuple型別。

Tuple Types:一個簡單Motivating例子

假如你想用一個函式返回多於一個返回值,例如:

// yields a quotient only


//


int IntegerDiv( int n, int d ) {


  return n / d;


}


 


// Sample use:


cout << "quotient = " << IntegerDivide( 5, 4 );


 


 在這個實現中有什麼錯誤嗎? 也許沒有,畢竟在中,我們內嵌了整數除法。包括結果也能夠四捨五入。


  但是,如果我們想做更多。特別,想提供一個方法得到除法其他的資訊,例如除法的餘數。如果沒有改變函式的結構。那麼,實現這樣的要求的函式不是一件容易的事情。


一種辦法我們在函式中加入一個輸出變數。


// Example 1(b): Integer division,


// yielding a quotient and remainder,


// one as the return value and one via


// an output parameter


//


int IntegerDivide( int n, int d, int& r ) {


  r = n % d;


  return n / d;


}


// Sample use:


int remainder;


int quotient = IntegerDivide( 5, 4, remainder );


cout << "quotient = " << quotient


<< "remainder = " << remainder;


 


這個方法的實現比較,但是我們經常這麼實現。這種透過返回值和輸出變數來返回函式返回值的辦法,看起來有點不可思議。有人也許會說下面的辦法更好。


// Example 1(c): Integer division,


// yielding a quotient and remainder,


// this time via two output parameters


//


void IntegerDivide( int n, int d, int& q, int& r ) {


  r = n % d;


  q = n / d;


}


 


// Sample use:


int quotient, remainder;


IntegerDivide( 5, 4, quotient, remainder );


cout << "quotient = " << quotient


  << "remainder = " << remainder;


這種辦法也許更加協調。但是 還是比較含糊,不令人滿意。稍微想一想,我們會記得為什麼:Ralph Waldo Emerson建議我們:“一個愚笨的一致性的想法是思想混亂的怪物”(a foolish consistency is the hobgoblin of little minds)。這個版本能夠正常工作,但是,如果你認為它不穩定的話,我不會責怪你。


那麼該怎麼做呢?在這一點我們通常會想起在標準庫中我們有一個工具:std::pair,畢竟在標準模板庫中有很多函式可以返回幾個值 ,iterator範圍就是作為一個單獨的值-同時,大多透過pair實現的,同樣的方法能夠執行,如下:


// Example 1(d): Integer division,


// yielding a quotient and remainder,


// this time both in the return value


//


std::pair IntegerDivide( int n, int d ) {


  return pair( n/d, n%d );


}


 


// Sample use:


pair quot_rem = IntegerDivide( 5, 4 );


cout << "quotient = " << quot_rem.first


  << "remainder = " << quot_rem.second;


可以看出這是一個滿意的做法,同時,它還可以提高。


Tuples in Action


  一些語言,包括Haskell, ML, 以及,都直接支援tuple types。C++不是這樣,這是因為C++是一個能做任何事情,和內建標準庫的語言,因此,我們能夠,以庫的形式實現我們自己的tuple types。像等語言是把tuple type作為pair一個系列打包在一起。一個 tuple


type和“bundle-o-values”很相像。


在下面一個tuple-ized 的IntegerDivide例子和上面pair-ized 是很相像的,但是,我們不要被迷惑了,畢竟它使用的是一種新的方法:


// Example 2(a): Integer division,


// yielding a quotient and remainder,


// via a type return type


//


tuple IntegerDivide( int n, int d ) {


  return tuple( n/d, n%d );


}


 


// Sample use:


tuple quot_rem = IntegerDivide( 5, 4 );


cout << "quotient = " << quot_rem.get<0>()


  << "remainder = " << quot_rem.get<1>();


這個例子的語法沒有pair那麼優雅,但是,它卻是和pairs一樣的簡單好用。


另一方面,typle 不侷限於只有兩個成員,它可以有任意多的成員,因此,它可以捆綁任何多個數值,我們來看下面的例子:


// Example 2(b): Floating-point division,


// yielding a quotient and remainder,


// but also an underflow


//


tuple // quotient, remainder, underflow


FloatDivide( float n, float d ) {


  // —


}


如果,我們使用std::pair來實現的話,那麼將會是這樣,std::pair >, (譯註:這樣大家也許能夠看出tuple的優勢了把)


  但是,我們不能老是把tuple作為bundle-o-values來使用。這裡有一些方法把來說怎樣把一些獨立的變數捆綁成tuple 。這是對於捆綁數值和解綁數值都是有用。例如,我們回到第一個關於除法例子   。


// Example 3: Bundling and unbundling


// using "tie"


//


tuple IntegerDivide( int n, int d ) {


  return tuple( n/d, n%d );


}


 


// Sample use:


int quotient, remainder;


tie( quotient, remainder ) = IntegerDivide( 5, 4 );


cout << "quotient = " << quotient


<< "remainder = " << remainder;


透過這種方法,我們就不用寫那些我們不喜歡寫的輸出變數了,Tuples有自己的輸入,輸出符號,和解壓運算子號。


// Example 4(a): Streaming tuples


//


tuple quot_rem = IntegerDivide( 5, 4 );


cout << quot_rem; // "(1 1)"


另一方面,如果,你想發揮一下你才智的話,你可以控制括號,和分界符。


// Example 4(b): Customizing streamed tuples


//


tuple quot_rem = IntegerDivide( 5, 4 );


cout << tuples::set_open('['] << tuples::set_close(')')


 


  << tuples::set_delimiter(',')


  << quot_rem; // "[1,1]"


你如果有興趣,你可以參考Boost中tuple的實現,(),


下期預告:


  在下一期裡,我將詳細講解function機制


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-998886/,如需轉載,請註明出處,否則將追究法律責任。

相關文章