Rob Murray分析的Obfuscated C++, 不懂STL的人可能看不懂。

myan 2001-02-25 12:43:00
Obfuscated C++

Rob Murray

. Last Month's Obfuscated C++

Last month we asked you to explain the output of the following program:
#include
#include
using namespace std;

template
void g(int size, op o, const char* sep = "") {
for(int i = 0; i < size; ++i)
cout << o(i) << sep;
}

template
struct w {
char* operator()(int a) {
return g(size,binder1st(op(),a),"\t"),"\n";
}
};

template
void
x(){
g(size, w());
}

int main(){
x,6>();
return 0;
}

This constructor of the x template prints a multiplication table of six rows and six columns, for example:
0 0 0 0 0 0
0 1 2 3 4 5
0 2 4 6 8 10
0 3 6 9 12 15
0 4 8 12 16 20
0 5 10 15 20 25

To understand how this works, we'll first examine the template function g(size,op,sep). op is a function object. The function object is "called" with the first size integers (starting at 0) and the results printed (separated by the string specified by the optional sep argument). We use this function twice.

The first call is in the template function x. It calls g, passing size and an object of type w<op,size>. For our example, this will call g(6,w<multiplies<int>,6>,""), which will cause the following invocations to occur:
w<'multiplies<int>,6>::operator()(0); //rownum = 0
w<multiplies<int>,6>::operator()(1); //rownum = 1
...
w<multiplies<int>,6>::operator()(5); //rownum = 5

Each of these constructors prints a single row of the table. It does this by creating a new function object
binder1st<multiplies<int> >(multiplies(),rownum)

where rownum is the row being printed. This binder1st object is passed to g(), which invokes operator() on the object for each of the integers from 0 to size-1. This prints a single row of the table, using a tab as the separator argument.

binder1st is a standard template class defined in the <functional> header. It takes a binary function object (in this case, multiplies<int>) and a single operand, and creates a new unary function object that "binds" the operand as the first operand of the binary function. This resulting object is invoked by calling operator(), passing a single operand. operator() returns the result of applying the original binary function to the "bound" operand and the operand supplied at the call.

In our example, the row index is "bound" as the first operand. For each column, the invocation of the binder1st object invokes multiplies<int>(int,int), passing the row and column indices respectively; the result is printed by g.

For bonus credit: Explain how the newline at the end of each row is printed.

Parameterizing the operation as a function object allows us to generate tables for other operations. For instance, x<plus<int>,4>() gives us:
0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6




This Month's Obfuscated C++

This month's Obfuscated C++ tests your knowledge of some of the standard template libraries. What is the output of the following program?
#include <iostream>
#include <list>
#include <iterator>
#include <algorithm>

struct {
void operator()(int i){cout<<i<<"\n";}
} c;
int main(){
list<int> il(2,1);
list<int>::iterator i1(il.begin()),i2(i1);i2++;
back_insert_iterator<list<int> >i3(il);
for(;*i1<20000;i1++,++i2)
*i3=*i1+*i2;
for_each(il.begin(),il.end(),c);
return 0;
}


...全文
255 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
myan 2001-02-25
  • 打赏
  • 举报
回复
始祖鸟老兄别怪, 我自己能作答的问题从来不给分. 不过,
um! 您的确是只老鸟!
第一个程序原文有问题, 我随后贴出正确程序.
ed9er 2001-02-25
  • 打赏
  • 举报
回复
um!20000这个值设的很好,打出来刚好一屏
ed9er 2001-02-25
  • 打赏
  • 举报
回复
没分?!算了,我来蒙第二个,是不是菲薄那吃数列?除非i++和++i的实现有很大差异,要不应该是的
vcmfc 2001-02-25
  • 打赏
  • 举报
回复
真的看不懂!
vcmfc 2001-02-25
  • 打赏
  • 举报
回复
真的看不懂!
在本书中,C++专家Rob Murray就与我们分享了他宝贵的经验和建议,以帮助初中级C++程序员得到进一步的提高。 在本书中,作者大量采用了实际开发中的代码来作为示例,向读者展示了那些有用的编程策略,并对那些有害的做法进行了警示。为了帮助读者更好地理解,在书中的每一章结束前,在该章中被介绍过的主要内容都被放到了一个列表中,此外,书中还给出了一些问题来激励读者们进行更多的思考和讨论。 本书在一开始就向我们讲解了如何为我们的设计选择正确的抽象,提示我们注意抽象和现实之间的区别。然后,我们就将学到如何将已得到的抽象转化成一个(或多个)C++中的类,期间进行的讨论所涵盖的范围上至高层的设计策略,下至底层的接口和实现细节。 接下来本书对单继承和多重继承进行了深入的探索。一开始书中会给出一个关于它们应该用在设计的什么地方的讨论,然后就是一些详细的示例代码,用来向我们演示如何在实践中使用这些概念。对于“如何构建可派生出其他类的类”以及“这么做的好处何在”,书中还专门抽出了一章来讨论它们。 对于C++中新增的模板特性,通过从基础开始到逐步地接触实际应用中的示例,Rob Murray向我们展示了其空前的洞察力。作者同时也向我们展示了多种特定的技巧,以使我们的程序更快、重用性更高,并且更健壮。异常是C++中另外一个新增的特性,对于何时该使用它,何时不该使用它,Murray也向我们给出了他的建议。在本书的最后,我们还可以学到如何将一个项目从C移植到C++之上,书中对该过程的讨论不但包括了其中可能出现的技术问题,也包括了使用技术的“人”的问题。 作者简介 Robert B.Murray在撰写该书时是量子数据系统公司(Quantitative Data Systems)中负责软件工程的副总裁,该公司的业务包括向财富500强(Fortune 500)中的公司提供面向对象的软件解决方案。在此之前,他曾经在AT & T的Bell实验室工作,在那里他参与了C++语言、编译器以及库的开发。他同时也是《The C++ Report》杂志的创立编辑(founding editor),主持Obfuscated C++专栏。从1987年起,他就开始在学术会议和专业会议上向人教授C++语言。目前Murray在FNIS公司进行着软件开发的管理,他的兴趣主要包括:程序语言的开发和工具,以及轻量级的开发过程(如极限编程)。 王昕,自1995年起接触C++编辑,参与过多个C++项目的开发。曾在网上和杂志上发表过多篇有关C++的文章。主要兴趣包括:程序语言的开发、形式化理论、软件开发方法学等。
Product Description The author uses practical, concise code examples to illuminate a useful programming stratagem or warn against a dangerous practice. Readers will come away with a better understanding of how C++ is used in the real world. From the Inside Flap In the hands of an expert, C++ helps designers and programmers build systems that are modular, maintainable, and fast. To the novice, however, the size of the language can be intimidating. There are a lot of features in C++ and it takes some experience to learn which ones are appropriate for any situation. This book is intended to enhance and expedite that learning process. Most successful C++ programmers cannot recite chapter and verse from the language rules; instead, they have acquired a set of idioms and techniques that have worked well for them. Our goal is to help the C++ novice learn those idioms that have been most useful in practice. We also point out some of the most common pitfalls. We do not try to cover the entire language and we leave the ultra-precise definitions of language semantics to the reference manuals. Instead, we concentrate on helping the reader build programs that can be understood by someone who is not a C++ language lawyer. We not only discuss techniques for making programs elegant and fast; we also show how to make them easier to understand and maintain. Acknowledgements Almost none of the ideas and programming idioms in this book are my invention. My goal has been to present, in a way that allows novice C++ programmers to learn them quickly, what I consider to be the most important strategies and tactics I have learned from others in the eight years I have been using C++. Some of these lessons were learned by studying actual development projects as they moved from C to C++; others came from discussions with talented individuals. Many of the best ideas on templates and library design, including the ideas behind many of the container classes in this book, came from classes in the USL Standard Components that were originally designed by Martin Carroll, Andrew Koenig, and Jonathan Shopiro. I claim exclusive ownership of any errors in my versions. Andrew Koenig was a valuable resource as the local C++ language lawyer. The participants in the "C++ Strategies and Tactics" seminars I presented at several conferences helped inspire this book and refine its ideas. Other important ideas came from Tom Cargill, John Carolan, Jim Coplien, Mark Linton, Gerald Schwarz, and of course Bjarne Stroustrup, who also invented the C++ programming language that made the book possible in the first place. Brian Kernighan read several drafts of this book, and his excellent feedback has been a lot of help. I would also like to thank David Annatone, Steve Buroff, Tom Cargill, Bill Hopkins, Cay Horstman, Lorraine Juhl, Peter Juhl, Stan Lippman, Dennis Mancl, Scott Meyers, Barbara Moo, Lorraine Weisbrot Murray, Bjarne Stroustrup, Clovis Tondo, Steve Vinoski, and Christopher Van Wyk for their comments on early drafts of this book. Lorraine Weisbrot Murray also contributed the encouragement, understanding, support, and love that helped make the entire effort feasible. Rob Murray

15,445

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧