热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

TuplesHerbSutter(陶章志译)

TuplesHerbSutter(陶章志译)就像我上期所报道的一样,在2002十月标准会议上,两个库扩展作为标准库延深,而被通过。<?xml:namespace
 

Tuples

Herb Sutter(陶章志译)

就像我上期所报道的一样,在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 = " <
 

  在这个实现中有什么错误吗? 也许没有,毕竟在编译器中,我们内嵌了整数除法。包括结果也能够四舍五入。

  但是,如果我们想做更多。特别,想提供一个方法得到除法其他的信息,例如除法的余数。如果没有改变函数的结构。那么,实现这样的要求的函数不是一件容易的事情。

一种办法我们在函数中加入一个输出变量。

// 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 = " <
<<"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 = " <
    <<"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 = " <
    <<"remainder = " <
可以看出这是一个满意的做法,同时,它还可以提高。

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 IntegerDivide( int n, int d ) {
  return tuple( n/d, n%d );
}
 

// Sample use:
tuple quot_rem = IntegerDivide( 5, 4 );
cout <<"quotient = " <()
    <<"remainder = " <();
这个例子的语法没有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 = " <
<<"remainder = " <
通过这种方法,我们就不用写那些我们不喜欢写的输出变量了,Tuples有自己的输入,输出符号,和解压操作符号。

// Example 4(a): Streaming tuples
//
tuple quot_rem = IntegerDivide( 5, 4 );
cout < // "(1 1)"
另一方面,如果,你想发挥一下你才智的话,你可以控制括号,和分界符
// Example 4(b): Customizing streamed tuples
//
tuple quot_rem = IntegerDivide( 5, 4 );
cout <
 

    <
    < // "[1,1]"
你如果有兴趣,你可以参考Boost中tuple的实现,(www.boost.org),

下期预告:

   在下一期里,我将详细讲解function机制


推荐阅读
  • 本文整理了Java中java.lang.NoSuchMethodError.getMessage()方法的一些代码示例,展示了NoSuchMethodErr ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了解决java开源项目apache commons email简单使用报错的方法,包括使用正确的JAR包和正确的代码配置,以及相关参数的设置。详细介绍了如何使用apache commons email发送邮件。 ... [详细]
  • 本文介绍了关于Java异常的八大常见问题,包括异常管理的最佳做法、在try块中定义的变量不能用于catch或finally的原因以及为什么Double.parseDouble(null)和Integer.parseInt(null)会抛出不同的异常。同时指出这些问题是由于不同的开发人员开发所导致的,不值得过多思考。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Python语法上的区别及注意事项
    本文介绍了Python2x和Python3x在语法上的区别,包括print语句的变化、除法运算结果的不同、raw_input函数的替代、class写法的变化等。同时还介绍了Python脚本的解释程序的指定方法,以及在不同版本的Python中如何执行脚本。对于想要学习Python的人来说,本文提供了一些注意事项和技巧。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了在Spring 3.1中,数据源未能自动连接到@Configuration类的错误原因,并提供了解决方法。作者发现了错误的原因,并在代码中手动定义了PersistenceAnnotationBeanPostProcessor。作者删除了该定义后,问题得到解决。此外,作者还指出了默认的PersistenceAnnotationBeanPostProcessor的注册方式,并提供了自定义该bean定义的方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • ***byte(字节)根据长度转成kb(千字节)和mb(兆字节)**parambytes*return*publicstaticStringbytes2kb(longbytes){ ... [详细]
  • 本文介绍了在Cpp中将字符串形式的数值转换为int或float等数值类型的方法,主要使用了strtol、strtod和strtoul函数。这些函数可以将以null结尾的字符串转换为long int、double或unsigned long类型的数值,且支持任意进制的字符串转换。相比之下,atoi函数只能转换十进制数值且没有错误返回。 ... [详细]
author-avatar
VI_宁小豆2502874431
这个家伙很懒,什么也没留下!
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有