这句话是在 C++ Standard Library : A tutorial and Reference 上看见的——there are rarely things that are not possible in C++
这句话出现在一个很不起眼的括号里面,却十分准确的描述了近段时间来我对C++的看法
正是因为持有这样的信念,总是觉得自己只尝到C++精妙的冰山一角,才引起了我对C++的喜欢
这段时间一直在忙于Project O,虽然还处于设计阶段,不过已经比起以前越来越清晰了
终于又找到了为了自己一直以来的一个目标,努力去奋斗的感觉
但是始终觉得这样的忙,会让自己忘却很多本来应该记住的东西,所以,有空一定要坚持写一写这个blog
或许在以后回想的时候,看着自己稚嫩的思想也有一番滋味
随性随便记点什么,先来点非常基础的东西
前置++,--和后置的++,--怎样用才更有效率?
其实我以前不是一个和效率较劲到如此地步的人,不过,这段时间看STL中,单独为前置和后置的增减运算符号留了一段。增减操作符号如果单独对于一个int仿佛不算什么大问题。
- int val = 10;
- val++;
- ++val;
这样程度的运用仿佛根本体会不到效率的损失,但是如果一个对象的复制过程成为了效率的绊脚石这里就会引起效率损失了。
- val++; //大致等同于下面这样的一段代码
- int increasePost(int& val)
- {
- int temp(val);
- val+=1;
- return temp;
- }
实际上,后置的增减操作符需要先构造一个临时变量(会引起复制的代价)。而实际应用中,我们有时候并不需要这个临时变量的产生(因为只有我们需要将自增前的值返回另有他用的时候才需要),而只是需要一个简单的自增操作。对于我们日常的语言,要想把一个数自增,仿佛很习惯就说到了a++(就是说 a+1),但是我们在C++里面真正体现这个语义的应该是前置的自增减操作符号。后置的自增减操作符表达的意思比后置的要多。
要多多少呢?这就得看复制一个对象的代价了,如果一个对象的复制过程需要一定的代价,那么我们为了一个额外的语义付出的代价就多了许多!
同样还是讨论效率的问题,STL的算法和容器的分开是出于泛型编程的目的。但是某些情况下就会出现一定的效率损失。
一个书上的例子
- list<int> coll;
- for (int i=1; i<=10; i++)
- coll.push_back(i);
- coll.erase(remove(coll.begin(),coll.end(),3),coll.end());
- //使用stl算法
- coll.remove(4);
- //使用成员函数
这里移除3的调用就比移除list中4的方法要低效得多。因为stl的算法 remove并不知道它工作在一个删除一个元素只需要O(1)的容器list上,所以它按照它的泛型心理工作,将要删除的元素后移,将后面的元素依次前移(就像在对连续空间的线性表做删除操作)。这样并没有发挥list这个双端链表的内部数据结构的优势~所以STL容器的成员函数如果能完成工作,应该优先使用成员函数,这样比较有效率。但是如果泛型是首要前提,就必须做出一些牺牲。
另外,前段时间大致理解了trait的意思。还在modern c++ design上看见了关于一个非常泛型的functor的实现。
也大致理解了偏特化这样的一个意思,或者可以说是,自己以前阅历不足,连这样的代码都没有看见过 - -!。
- <int val>
- class add
- {
- public:
- int operator()(int argu) {
- return argu + val;
- }
- }
如此,这个function object就可以这样使用 add plus_ten<10>; cout<<plus_ten(20)<<endl;
这样其实应该叫一个模板的特化,而偏特化在我理解应该是类模板拥有2个或以上的模板参数的时候,特化其中一部分得到的类模板实现。