Tuples Herb Sutter
当前位置:以往代写 > C/C++ 教程 >Tuples Herb Sutter
2019-06-13

Tuples Herb Sutter

Tuples Herb Sutter

副标题#e#

就像我上期所报道的一样,在2002十月尺度集会会议上,两个库扩展作为尺度库延深,而被通过。

1 是Doug Gregor’s提出的多态函数的object wrappers。

2 Jaakko Järvi’s提出的tuple范例。

这两个都是直接来在Boost项目。(Boost项目是一个C++ libraries 荟萃)上次,我承诺在这期和下一期将先容这两个扩展的库,这个月,就让我来简朴的先容一下tuple范例。

Tuple Types:一个简朴Motivating例子

如果你想用一个函数返回多于一个返回值,譬喻:

// yields a quotient only
//
int IntegerDivide( 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<iterator,iterator>实现的,同样的要领可以或许运行,如下:

// Example 1(d): Integer division,
// yielding a quotient and remainder,
// this time both in the return value
//
std::pair<int,int> IntegerDivide( int n, int d ) {
return pair<int,int>( n/d, n%d );
}
// Sample use:
pair<int, int> quot_rem = IntegerDivide( 5, 4 );
cout << "quotient = " << quot_rem.first
<< "remainder = " << quot_rem.second;

可以看出这是一个满足的做法,同时,它还可以提高。


#p#副标题#e#

Tuples in Action

一些语言,包罗Haskell, ML, 以及Python,都直接支持tuple types。C++不是这样,这是因为C++是一个能做任何工作,和内建尺度库的系统语言,因此,我们可以或许,以库的形式实现我们本身的tuple types。像java等语言是把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<int,int> IntegerDivide( int n, int d ) {
return tuple<int,int>( n/d, n%d );
}
// Sample use:
tuple<int, int> quot_rem = IntegerDivide( 5, 4 );
cout << "quotient = " << quot_rem.get<0>()
<< "remainder = " << quot_rem.get<1>();

这个例子的语法没有pair那么优雅,可是,它却是和pairs一样的简朴好用。

另一方面,typle 不范围于只有两个成员,它可以有任意多的成员,因此,它可以绑缚任何多个数值,我们来看下面的例子:

#p#分页标题#e#

// Example 2(b): Floating-point division,
// yielding a quotient and remainder,
// but also an underflow
//
tuple<float, float, bool> // quotient, remainder, underflow
FloatDivide( float n, float d ) {
// —
}

假如,我们利用std::pair来实现的话,那么将会是这样,std::pair<float, std::pair<float, bool> >, (译注:这样各人也许可以或许看出tuple的优势了把)

可是,我们不能总是把tuple作为bundle-o-values来利用。这里有一些要领把来说奈何把一些独立的变量绑缚成tuple 。这是对付绑缚数值息争绑数值都是有用。譬喻,我们回到第一个关于除律例子  。

// Example 3: Bundling and unbundling
// using "tie"
//
tuple<int,int> IntegerDivide( int n, int d ) {
return tuple<int,int>( 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<int, int> quot_rem = IntegerDivide( 5, 4 );
cout << quot_rem; // "(1 1)"

另一方面,假如,你想发挥一下你才智的话,你可以节制括号,和分界符。

// Example 4(b): Customizing streamed tuples
//
tuple<int, int> quot_rem = IntegerDivide( 5, 4 );
cout << tuples::set_open('['] << tuples::set_close(')')
<< tuples::set_delimiter(',')
<< quot_rem; // "[1,1]"

你假如有乐趣,你可以参考Boost中tuple的实现,(www.boost.org),

    关键字:

在线提交作业