[声明]:本英文资料源自于Herb Sutter 创建的“Conversation”栏目,“C++ 翻译小组”的翻译作品供学习交流与参考用途,不得用于任何商业用途。未经Herb Sutter、Jim Hyslop同意,不得转载;对于违反以上条款,翻译小组对此不负任何责任;特此声明。
文章来源:http://www.gotw.ca
版权归属:Herb Sutter and Jim Hyslop
译 者:csdnfriend(CSDN)
对话:#10 关于操纵器的对话
那天一开始和以前一样没什么两样。
我早早就起了床,抓紧时间看了一些技术文章,然后在食堂大厅里吃早饭,去换班的时候还提前了五分钟。这轮班本来就是例行公事,并没什么大事发生。但临近下班时,怪事发生了。距离换班整整还有十分钟,布拉森科沃斯基居然晃了进来,准备接我的班。
真是太阳从西边出来了,布拉森科沃斯基干任何事情都不会提前。但我实在想不出今天他为什么提前。他查看了一些物件后,走过来对我说,“嗨!弗兰奈尔找你有事,回去时顺便弯一下她住的特等舱。”
“哦?什么事?”
“不知道,” 布拉森科沃斯基耸了耸肩。接着他又微微一笑,轻轻地拍了拍我的背。“你最好还是过去吧,”他补充道,“这里有我顶着。”
“是啊,轮到你了,”我表示同意,接着又叹了口气,出门而去。
当我到弗奈尔的船舱里,门已经打开了。她招手让我进去,身后的门轻轻关上。她的客椅上已坐着另外一位男士。我以前好像没见过他。
“嗨,嗨”他的声音很友好,站起来握我的手。
“这是主管吉尔伯,”弗奈尔给我们介绍了一下,于是坐了下来。
“听说您可以去圆屋帮助我们?”吉尔伯单刀直入。
我看了弗奈尔一下:“是的,只要我能行。”
“哦,我想你肯定行,”吉尔伯信誓旦旦地说,“你原先是跟珍妮.卡露莎一块干的吧。是的,她现在在我的部门,而且她对你评价很高,对,非常高。我知道你现在负责的日常工作越来越多,”他接着说道,“但在研究现场工作更有挑战性。怎么样?感不感兴趣?”
“是的。这样很好。我已经要求参加更多跟研究有关的工作。”
“很好,很好。我相信薪水也很合适。是的,很合适。你当然明白在那里要呆上一段时间,至少等我们有能力恢复这几座建筑物和圆屋之间的正常交通。现在逼不得已才使用这个临时过道。”
他开始问我一大堆问题。我什么也不记得了。脑袋有点飘飘然,但还是高兴地意识到又可以见到珍妮了。真滑稽,我想,这和年轻时交上女朋友有点不一样,跟那时不太一样,那时我刚参加工作,很多年以前了……
- - - - - - - - - - - - - - - - - - - - - - - - -
“肯定有更好的方法,”我咕哝着。
“嗨,伙计,怎么了?”温迪愉快的嗓音在小屋里缠绕。我伸了伸腰决定暂停编码休息一会,于是地鼠般地弓起身来。
“太好了,”我回答道,“你回来了?我以为你要出去两周呢?”
她白了我一眼:“你去哪里了,木星吗?我已经旅游两周并且度过了周末假!”
“开心的时候时间过得飞快,”我偷偷笑了笑。
“哼,”她说道,“你跟安娜去哪儿了!知道吗?我告诉过你Guru的party会很有趣的,没想到你带着她女儿在外面泡。”
“诶,前几周我并不知道她是的Guru女儿,”我抗议道,“我以为她只是party的一个客人。”
“吃午饭时你慢慢告诉我。”她把雨靴塞到桌子下边又换上了便鞋。“还有,这里怎么了?我进来时气氛有点紧张。”
“好吧,拉一个椅子过来我会告诉你血淋淋的事实。说不定你有什么新的见解。”等温迪走进我的小屋,我又坐进椅子里。
“我在我们的系统上实现一些通讯功能。使用一种很简单的协议。服务端只是返回一系列以逗号作定界符的带引号的字串。因为字串可以带引号,所以我写了一个简单的函数来处理字串,在字串两端加上引号,而字串内部的引号则作转义处理,就像这样,”我在白书写板上演示给她看:
Input
Output
field 1
"field 1"
field "with quotes"
"field \"with quotes\""
“我写了两个函数,一个用来加引号,另一个用来去掉引号:
std::string quote(const std::string &);
void f(std::ostream &o)
{
o << quote("whatever");
}
std::string unQuote(std::string &);
void g(std::istream &i)
{
std::string input;
i input;
std::string original=unQuote(input);
// use string 'original' ...
}
“不错,很直截了当,”温迪答道,“这是典型的你用于文本文件解析器的思路。”
“是的,是很简单。但如果原始字串很长,我只好拷贝整个字串。我们的服务器软件必须很紧凑,因为它是在我们所制造的那些箱子里运行的。而且,项目组有些成员抱怨这样使用起来显得很笨拙,他们希望可以使用流插入和提取。像这样,”我用力地在白书写板上写出如下代码:
std::string message;
// aStream is an istream subclass
aStream message;
“我必须设法将文本放进aStream,再从中提取一个字段的内容到message中。我已经在流缓冲区里折腾了好半天,但还是不怎么行。”
“用操纵器。”听到Guru温和的嗓音时,温迪和我跳了起来。
“什么?”我问。
“写你自己的IOStream操纵器,就像Langer和Kreft刚在C++ Repot中所描述的那样[1]。”
“唔,你是说先知Langer和Kreft?”我问。
“鲍勃在开会,我现在没有精力来充当Guru,”她耸了耸肩。即使她不摆出Guru的派头,我心里还是把她当成Guru。而且她总是在关键时刻神秘地出现!我开始怀疑她是否在附近布置了眼线。
“啊,”我说,一边奇怪为什么我的回答总是如此软弱。“那么怎么写一个IOStream操纵器呢?”
“有两种方法,取决于你实现的操纵器有没有参数。如果你的实现中要处理一个参数,接下来我会完整地描述给你听。如果你还想知道怎样实现没有参数的操纵器,你可能得再翻翻以前的一些东西了。
“实现带一个参数的操纵器实际上很简单。你只要简单地创建一个类,在其构造函数中接收适当的参数,并提供插入和提取操作符,操作符内部调用一些操作操纵器的成员函数。比如你要写一个ostream的操纵器来操纵一个整数,可以这样做。” Guru擦掉白书写板上的字,用她细长好看的字体整洁地写出如下代码:
class myManipulator
{
int manipValue;
public:
explicit myManipulator(int i) : manipValue(i) {} // Note it's 'explicit'!
friend ostream & operator <<(ostream &os, const myManipulator &mm);
};
“使用操纵器很简单,就像使用std::setfill和std::width一样:”
“编译器将产生一个临时的无名myManipulator对象,使用42来初始化它。接着编译器调用重载的插入操作符。插入操作符对流执行必要的操纵,就像下面这样:”
ostream & operator <<(ostream &os, const myManipulator &mm)
{
if (mm.manipValue == 42) {
os << "Life, the universe, and everything";
} else {
os << "What was the question, again?";
}
return os;
}
我想了一下。“那么…”我小心地问,“我的ostream操纵器可以使用字符转义和反转义吗?”
“你可以这么做,也可以分开两个不同的类来实现转义和反转义[2],escape 及 unescape [2].”她突然停住了,露出了微妙的变化。这时,鲍勃走了过去,是要去咖啡屋。“记住,孩子,” Guru接着说,“多读、多想先知Kreft和Langer的文章。”
“是,老师,下午给你看我的结果”我回答。鲍勃停了下来,他的杯子掉在了地板地毯上。他拿起杯子,没有回头走了。当他在视野里消失之后,温迪,Guru和我交换了一下眼神。是的,我们就想达到这样的效果。
- - - - - - - - - - - - - - - - - - - - - - - - -
主管吉尔伯可没想这么多,至少此时没有。过了一会他接下去说:“是,是的,你会做得很好。欢迎加入这个小组。”
我们握了握手,我张嘴笑了:“谢谢。我什么时候调您那边?”
“什么?噢,你已经是了。不用担心行李。你的东西已搬到圆屋了。你值班时他们已经行动了,都办好了。 ”
我还没明白过来,已经被带走进了一部停在中转站的轿车。吉尔伯还在愉快地小声交谈时,车门关上了,我们加速驶进了开往圆屋方向的通道。
[注释]
[1] Klaus Kreft and Angelika Langer. "Effective Standard C++ Library", C++ Report, April 2000.
[2] A complete, working example of the narrator's manipulators is available on the CUJ website at
hyslop.zip.
[关于作者]
Herb Sutter
是个独立顾问,也是ISO/ANSI C++标准委员会的秘书。你可通过hsutter@acm.org.联系他
Jim Hyslop
Leitch Technology International Inc.资深的软件设计师,你可通过jim.hyslop@leitch.com联系他