The C++ Standard Libary, A Tutorial and Reference:笔记

Nicolai M. Josuttis(侯捷,孟岩译):The C++ Standard Libary, A Tutorial and Reference,华中科技大学出版 ,2002年9月
2007-08-21 13:53:50

pp.10 Nontype Template
bitset<32> flag32;

pp.11 typename
template <class T>
class MyClass {
    typename T::subtype* ptr;
    ...    //此处如无typename,编译器会识别subtype为T的static成员
};
MyClass<Q> X;
Class Q{
    typedef int subtype;
};


pp.16 如果声明一个空白异常规格,那就表明该函数不会抛出任何异常
void f() throw();
违反异常规格,会导致(pp.27) -> unexpected() -> terminate()

pp.17 namespace定义的是逻辑模块,
而非实质模块,模块在UML中是package
namespace可在不同文件中扩展

pp.20 constant static members
class MyClass {
    static const int num = 100;
    int a[num];
};
const int MyClass::num;

pp.36 make_pair()隐式指定type
make_pair(42, 7.77)
=> pair<int, double>(42,7.77)

pp.38 auto_ptr的
主要动机是避免异常造成的memory leak

pp.39 auto_ptr的限制
1.无指针算术( 包括++)
2.禁止assign初始化
std::auto_ptr<ClassA> ptr1(new ClassA); //ok
std::auto_ptr<ClassA> ptr2 = new ClassA; //error

pp.40 auto_ptr ownership
初始化赋值,参数传递,返回值,会有owership转移
pp.42指出,[auto_ptr的语义本身就包含了拥用权。所以如果你无意转交你的拥有权,就不要在参数列中使用auto_ptr,也不要以它作为返回值。]
pp.39指出,[auto_ptr要求一个对象只能有一个拥有者,严禁一物二主。]

pp.44 const auto_ptr;
成员变量可用之避免ownership转移。
可更改auto_ptr所拥有的对象,
不可更改auto_potr的拥有权。
const std::auto_ptr<int> p(new int);
std::auto_ptr<int> q(new int);
*p=42;    //change value to which p refers.
bad(p);    //compiler error
*p=*q;    //change value to which p refers.
p=q;        //compiler error
return p;    //compiler error

p.49 不能以赋值操作初始化auto_ptr
std::auto_ptr<int> p (new int(42)); //ok
std::auto_ptr<int> p (new int(42)); //error

pp.64 number_limits<>的使用
cout << number_limits<short>::max();

pp.69 比较操作符
std::rel_ops::operat
!=, >, <=, >=
基于==和<完成

pp.75 container
sequence,排列次序和置入次序一致
associative,位置取决于元素值,与插入次序无关
可使用二分法查找,自动排序是一个(有用的)副作用。

pp.81 关联式容器
在实现中,关联式容器由二叉树实现
左子 <= 父 <= 右子
二叉查找树

pp.94 算法...是一种搭配迭代器使用的全局函数。

pp.106 inserter(container, pos),
其中pos仅供提示。从什么地方开始搜索正确的安插位置。在关联式容器中,元素位置由key决定。

pp.113 移除元素,置新区间
list<int>::iterator end = remove(coll.begin(), coll.end(), 3);
coll.erase(end, end());

pp.115 删除关联容器的元素,用成员函数
set<int> coll;
int num = coll.erase(3);

pp.127 funcotr的优点
1.初始化
√2.每个functor都有自己的类型,即使signatures相同
pp.130
    AddValue addx(x);
    Addvalue addy(y);
for_each(coll.begin(), coll.end(), addx);
for_each(coll.begin(), coll.end(), addy);
3.functor函数快
因为先完成初始化,template class可在编译时进行

pp.133 bind2nd(equal_to<int>(), 70)
以70作为第二参数,调用二元谓词equal_to,
从而定义出一个一元谓bind2nd,处理coll内的每一个元素
replace_if(coll.begin, coll.end()),
    bind2nd(equal_to<int>(), 70),
    42);

pp.136 STL容器中的元素为value,不是reference
存放指针时,比较动作的对象是指针,而非指针指向的对象

pp.147 以标准输入完成初始化操作
    std::deque<int>
        c( ( std::istream_iterator<int>(std::cin) ),
        (std::istream_iterator<int>() ) );
无此括号,c被视为函数

pp.149 reverse()为vector保留容量

pp.150 临时变量调用non-const成员函数
std::vector<T>(v).swap(v);
会shrink capacity

pp.171 list特殊变动性操作
c.unique(),移除相邻重复元素,只留下一个。
c1.splice(pos, c2),把c2中所有元素移到c1中,post前。

pp.176 红黑树
节点安插时最多做2个重新连接,
最大路径深度是最短路径深度2倍

pp.182 set, vector等的插入, remove
1.由于set改变元素值会引起元素位置改变,因此不能使用remove算法, 只能使用成员c.remove(elem)
iterator是const
2.vector插入、移除会导致iterator失效

pp.180 set搜寻函数
find(elem) 第一个元素elem
lower_bound(elem) 第一个可安插位置
  1    2    4    5    6
            -    -    -
            |    |    |
            |    |    +---------upper_bound(5)
            |    +-----------------lower_bound(5)
            +-------------------------upper_bound(3)
equal_range(elem)
pair(5,6)

pp.203 value_type
    std::map<std::string, float> coll;
    coll.insert(std::map<std::string, float>::value_type("otto", 22.3));
等价于
    coll.insert(std::make_pair("otto", 22.3));

pp.228 排序速度
hash table(未标准化)通常比binary tree快5-10倍
关联式容器每次插入都要排序,有时不如 vector全插入,然后调用排序算法 速度快

pp.258 vector::iterator递增的编译错误,string::iterator
sort(++coll.begin(), coll.end());
如果vector::iterator被实现为指针,编译会出错,
因为C++禁止修改任何类型(含指针)的临时值

pp.273 back_insert_iterator<vector<int> > iter(coll);
                      ----
                       +-------------push_back
    front_insert_iterator
        => insert_iterator<set<int> > iter(coll, coll.begin())    //任意位置

2007-08-23 14:18:18整理

pp.267 逆向迭代器位置
rbegin()指向最后元素的后一个位置rend()指向最首位的元素。
reverse_iterator rpos(pos);
        +----pos
1 2 3 4 5 6 7 8 9
      +------rpos

pp.280 end_of_stream iterator
用istream迭代器的默认构造函数生成
pp.283 if(cinpos!=istream_iterator<string>())

pp.288 iterator_traits
    namespace std{
        template <class T>
        struct iterator_traits {
            typedef typename T::value_type value_type;
            typedef typename T::difference_type difference_type;
            typedef typename T::iterator_category iterator_category;
            typedef typename T::pointer pointer;
            typedef typename T::reference reference;
        };
    }
    pp.288
    class Myiterator
        : public std::iterator <std::bidirectional_iterator_tag, type, std::ptrdiff_t, type*, type&>
    {...}

pp.304 谓词functor的要求
不应传递"行为取决于被拷贝次数或被调用次数"的functor
谓词应总是返回相同结果,对于相同参数;即谓词不应有可观察的状态

pp.307 成员函数的函数配接器
for_each(coll.begin(), coll.end()
    mem_fun_ref(&Person::print));    //const成员
pp.310 ptr_fun //一般函数
可以与bind2nd配合,实现单参函数调用

pp.311 自定义functor使用函数配接器
template <class T1, class T2>
struct fopow::public std::binary_function<T1, T2, T1>
{
    T1 operator() (T1 base, T2 exp) const( return std::pow(base, exp);)
}
...
transform (coll.begin(), coll.end(),
    ostream_iterator<int>(count, " "),
    bind2nd(fopow<float, int>(), 3));


pp.329 排序算法
sort        quicksort    nlog(n)
partial_sort    heapsort    nlog(n)    //多数时间慢于quicksort 2~5倍
stable_sort    mergesort

p.331 已序区间的算法
binary_search
includes
lower_bound, upper_bound, equal_bound
merge,复制到新位置
set_union, set_intersection, set_difference, set_symmetric_difference (只出现于两区间之一的元素集合)
inplace_imerge,位置在前区间开始处

pp.325 for_each与transform的不同
for_each, by reference,改变原值
transform,改变后的值复制到目标区间(可与原值相同)

pp.349 search "偶,奇,偶"子序列
bool checkEvenArgs[3] = {true, false, true};
pos = second( coll.begin(), coll.end(),
    checkEvenArgs, checkEvenArgs + 3,
    checkEven );
    ---------
       +-----------全局函数

pp.366 copy_backward
copy_backward(c2.begin()+10, c2.begin()+16,
    c2.begin()+9 );
    ------------
         +---------------目标区间终止位置之后
source: ..........abcdef..........
c2:     ..........abcabcdef
                  +     +  +
                  10    16 19

pp.369 transform
1.调用者必须保证第二源区间有足够空间;
2.调用者必须保证目标区间有足够空间,否则使用插入型迭代器。

pp.378 remove
-remove不可应用于关联容器,使用erase
-list使用成员函数remove
-移除后使用新终点

pp.389 rotate
类似于循环左移(或右移)

pp.459 priority_queue::top() 返回优先级最高元素

pp.459,238 front,返回首元素

pp.462 bitset
bitset<numeric_limits<unsigned long>::digits>(267);
bitset<24>(1e7); //十进10,000,000用24位二进制表示
bitset<100>(string("1010101")); ( pp.464)

pp.485, 487 string函数在non-const函数后失效
non-const函数:s+="ext";
失效:
const char* p=s.c_str();    //在not-const前取得的值
char& r=s[2];        //non-const后失效


pp.484 c-string
data()后返回字符数组,不含''
copy(),复制到目标字符数组,不含''
c_str(),返回c-string,含''

pp.496 npos
if(s.find ("hi")==std::string::npos)
不使用临时变量,避免unsigned short/unsigned long的-1值不同
static const size_type npos = -1;

pp.517 避免二义性
s.insert((std::string::size_type)0, 1, ' ')
指出0不是iterator(可能实现为char*)

pp.592 iostream提速
static ios_base::sync_with_stdio(false);
在IO前调用,禁止与c标准库中相应文件stdio,stdout,stderr同步

pp.594 <<
只代表输出次序,不代表计算次序。

pp.599 clear
1.fail后要明确清除错误标记
strm.clear()
2.置位。检查failbit,如是,则清除
strm.clear(strm.rdstate() & ~std::ios::failbit)

pp.600 while(cin)
stream定义了可用于bool表达式的函数
operator void* () => !fail()
operator !()    => fail()

pp.618 对齐,宽度
执行了格式化I/0操作后,width恢复为默认值;fill不变,除非明确修改
width对于输出是最小宽度,不截尾
width对于输入是最多读入的宽度

pp.626 ios::nounitbuf
每次写出后,不清空output缓冲区

pp.634     basic_istream<>::tellg()
get
    basic_ostream<>::tellp()
put

pp.636 file.clear ()
清除fail/eof等,以便继续读写

pp.637 tie
每个stream只能tie一个output stream指针
保证在输入/输出前,先清空output stream
std::cin.tie(&std::cout);
及std::cin.tie(static_cast<std::ostream*>(o))

pp.639 共用buffer
ostream hexout(cout, rdbuf());
hexout.setf(ios::hex, ios::basefield);
hexout.setf(ios::showbase);
hexout << ...
cout << ...
共用缓冲,不共用格式

pp.642 重定向
ostream file ("something.txt");
old = cout.rdbuf(file.rdbuf);
...
cout.rdbuf(old); //记住恢复buffer

pp.649 string stream
-strstream是旧标准,仅用于向下兼容
-新:
    include <sstream>
    istringstream
    ostringstream
    stringstream
    stringbuf
    stringstream::str()
    stringstream::str(string)

pp.657 以辅助函数完成I/O(建议方案)
如使用 继承+friend 缺点:
friend不能成员虚函数
如果基类指针指向派生类,并作为input操作符参数,则被调用的是基类的操作符

pp.727 allocator
作为template参数传入
用于分配容器的内存空间,初始化elements
1.tempalte<class T, class Allocator=allocator<T> >
    class vector{
        private:
        Allocator alloc;
        T* elems;}
2.一个vector构造:
    template <class T, class Allocator>
    vector <T, Allocator>::vector
        (size_type num, const T& val,
        const Allocator& a)
        :alloc(a)
    {...
        elems = alloc.allocate(num);
        ...           --------
        for(...)    +
        {               +->基本的空间分配:分配,生成,销毁,回收
                  __+______
            alloc.construct(&elems[i], val);
        }
    } //根据元素个数num及数值val初始化vector

pp.728 非缺省Allocator
不同Alloctor配置出的元素不是同一类型,可用下面代码比较类型:
if(mymap.get_allocator()==s.get_allocator())

pp.* 缓冲
1.pp.682 sync_with_stdio(false)
不同C标准库同步
须在所有I/O前调用
2.p;683 unitbuf,每次输出后,stream清空缓冲
flush,endl
默认除cerr,weer外,nounitbuf

pp.* 国际化
未看

pp.668 自定义stream buffer
output:
putbase     put_pointer      end_of..
pbase()     pptr()           epptr()
 |           |                |
 V           V                V
+-+---------+-+-------------- +-+
| |         | |              | |
+-+---------+-+--------------+-+
input:
+-+---------+-+--------------+-+
| |         | |              | |
+-+---------+-+--------------+-+
 |           |                |
 V           V                V
eback()     gptr()           egetptr()
end back

pp.667 stream buffer iterator
    istream_iterator<char> inpos(cin);
    istream_iterator<char> endpos; //end of 调用iterator构造

    ostream_iterator<char> outpos(cout);
    while(inpos!=endpos)
    {
        *outputs = *inputs;
        ++inpos;
        ++outpos;
    }
    典型的filter framework。输出所有读入字符

笔记 2007年08月11日 16:59

排课程表软件

 
 

via Freeware Home -- new additions on Aug 17, 2007

FET is an Open Source, evolutionary program (using a genetic algoritm) for automatically generating the timetable of a school, high-school or university. It aims to have the same functionality as expensive scheduling programs. Features include: multi-lingual; automatic generation algorithm also allows semi-automatic or manual allocations; view the currently generated timetable without stopping the ongoing simulation; very flexible students structure in years, groups and subgroups - allows overlapping years and groups and non-overlapping subgroups. (in Education)

 
 

Things you can do from here:

 
 

我是一个什么样的程序员

在[http://www.doolwind.com/index.php?page=11]测试的。
Your programmer personality type is: PLTCYou're a Planner.
You may be slow, but you'll usually find the best solution. If
something's worth doing, it's worth doing right.
You like coding at a Low level.
You're from the old school of programming and believe that you should
have an intimate relationship with the computer. You don't mind
juggling registers around and spending hours getting a 5% performance
increase in an algorithm.
You work best in a Team.
A good group is better than the sum of it's parts. The only thing
better than a genius programmer is a cohesive group of genius
programmers.
You are a Conservative programmer.
The less code you write, the less chance there is of it containing a
bug. You write short and to the point code that gets the job done
efficiently.

帮忙与责任(转发)

发信人: j2k (没有开始,也没有结束,只有道路在消失), 信区: RunningLife
标 题: 帮忙与责任
发信站: 水木社区 (Fri Jun 8 00:53:18 2007), 站内 协会例会开完,泛泛而谈,若心有所动,反躬自省 常常喜欢把帮忙挂在嘴边,比如找老同学帮忙办个事情,比如找辅导员帮忙联系工作,比如找老师帮忙高抬贵手,当然被别人找上门也不少,比如帮忙到图书馆借个书,比如帮忙到邮局寄封信,比如帮忙买个礼物送回家,比如…… 很多吧,数不清楚了。 不过还有很多时候,不是用帮忙这个词,而是用责任,或者另外相近的,例如工作、要求、任务……不过我喜欢"责任",工作好像太宽泛了,工作还可以打盹呢,要求似乎有些机械,是别人的要求,和自己没有关系,任务就更夸张了点,极端反感这样的说法,那还是用"责任"吧。"责任"是近代才有的,古代
"责"的意思是"差事",估计和"任务"类似,"任"的意思是"职责",偏重担当。 这个例子也很多,比如今天打扫卫生是我的责任,比如明天升旗是我的责任,还有比如晚会的灯光是我的责任等等。很多,也数不清。 认真想想,"帮忙"大概重于关系,血缘、地缘、人缘都算,简单说就是人际关系,处好了,别人给你帮忙,处不好,当然就不帮忙。想起以前看过《乡土中国》,费孝通的一本薄薄的册子,极白话,其中提到中国传统社会是"差序格局",有一个很形象的比喻就是"以己为中心,像在水中投入的石子,水的波纹一圈一圈推出去,越远越薄"正好在《说文》中对于"伦"的解释是"伦也,水文相次有伦理也",多么形象。大概帮忙就是这个层面的意思了,你靠石子近,就容易帮忙,否则就越远越薄嘛。不过既然是水的波纹一样,你就不知道到底有没有波及到你,振幅虽然不断削减,不过总还是有那么点点微波,这个远和近太模糊了,
"帮忙"的界限就很模糊,到底他会不会帮忙呢?我忐忑不安中,也许明天就不帮忙了也说不定。 "责任"好像和这个一点关系都没有,"责任"就是一种权利和义务的匹配关系,你有你的责任,他有他的责任,不在乎他离开你远就没有责任了,也不在乎离你近这个责任就大了一些,等间距的,就好像一捆木头,有的承担多一点的捆绑压力,有的少一些,不过总是明确的。不过这个"责任"往往是有界限的,正如一捆木头,总是在这个捆的范围内,譬如我的责任是打扫教室,那隔壁就不是我的范围,甚至就今天,明天也不是我的范围了。虽然也许你要我来打扫你家不可得,也许会扫你的兴,不过教室我可认认真真打扫干净了。 一个团队,可以是"帮忙"的,也可以是"责任"的,比如我的好朋友组成个团队,那我们就是互相帮忙的性质,谁也没有必然的责任,不过谁都可以付出很大的"帮忙",如果两个恋人,那更是一个"帮忙"为主的团队。公司里面,好像大多数是"责任",很难听说老板让员工"帮忙"完成工作的,也许有时候话语上不免温柔体贴,不过试试如果你超过一定期限不干活,照样炒鱿鱼,当然不排除家族企业里面裙带之风,那你不上班都没有关系,此为另话。 一块石子再大,波纹也会很快消失到无法振动其他水花,这是常识,当然太阳可以不断掀起潮汐巨浪,不过太阳估计也管不到天狼星的潮汐吧。一捆木头则不然,你可以捆多一点,多捆几把然后再扎起来,堆垛起来,甚至是堆成小山,恐怕都是可以的,木头不用太粗,也不必一定都是实心木头,空心都无妨,巧妙的捆绑堆垛,还是可以承受很大压力的吧。 团队就是这样,也许开始后创业就两个好兄弟,发展到一定程度,还是要亲兄弟明算账,中苏关系够铁吧,还不是倒戈相向;太宗兄弟够亲吧,还不是玄武门血溅当场;希望集团五兄弟够意思吧,最后也分开各干各的了。要壮大起来,靠几块石子是做不来的,还得靠一捆一捆的木头。
--
炎炎夏夜皎皎明月心烦意乱无心睡眠 浩浩队伍盈盈笑语跑步健身吃瓜联欢
┌┬┐┌┬┐┌┬┐┌┬┐ ˇ ● ˇ┌┬┐┌┬┐┌┬┐┌┬┐
○ ├夜┤├间┤├跑┤├步┤� � ├有┤├氧┤├健┤├身┤ ▲
<�- └┴┘└┴┘└┴┘└┴┘ └┴┘└┴┘└┴┘└┴┘ �●
/> 清华马协2007夏季夜间跑步活动 RunningLife/跑道人生 ∧■
※ 修改:・j2k 于 Jun 8 08:16:19 修改本文・[FROM: 202.108.12.*]
※ 来源:・水木社区 newsmth.net・[FROM: 202.108.12.*]