Hello from lk's World
12 May 2014 » 从 std::ratio 看编译期运算
<ratio>
提供了 编译期 分数运算功能(还记得当年 OOP 课上要写一个分数类,不过是运行时的)。编译期呢,也就是说分母(numerator)和分子(denominator)都是在编译期时就是确定的,并且在编译期完成所需的各种运算。
先抄一个 ratio 使用的例子:
#include <iostream>
#include <ratio>
int main ()
{
typedef std::ratio<1,3> one_third;
typedef std::ratio<2,4> two_fourths;
typedef std::ratio_add<one_third,two_fourths> sum;
std::cout << "sum= " << sum::num << "/" << sum::den;
std::cout << " (which is: " << ( double(sum::num) / sum::den ) << ")" << std::endl;
return 0;
}
10 May 2014 » containers,unordered 系列与 hashtable
总算把中期报告搞定了,可以继续搞起。 C++11 中, 多了 4 个 unordered 容器,分别是 unordered_set, unordered_multiset, unordered_map, unordered_multimap。当然,也略有耳闻里面是用 hash table 来做的,今天一探究竟。
先来看看 unordered_map, include/bits/unordered_map.h
template<class _Key, class _Tp,
class _Hash = hash<_Key>,
class _Pred = std::equal_to<_Key>,
class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class unordered_map
{
typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable;
_Hashtable _M_h;
发现里面有一个 _Hashtable,相似的在 multimap 中。
template<class _Key, class _Tp,
class _Hash = hash<_Key>,
class _Pred = std::equal_to<_Key>,
class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class unordered_multimap
{
typedef __ummap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable;
_Hashtable _M_h;
05 May 2014 » containers,inside std::deque
继续 container ~ 来到 inlcude/bits/stl_deque.h 假设我们对 deque 的内存布局一无所知,然后来看代码看看能不能看出蛛丝马迹。
/**
* @brief This function controls the size of memory nodes.
* @param __size The size of an element.
* @return The number (not byte size) of elements per node.
*
* This function started off as a compiler kludge from SGI, but
* seems to be a useful wrapper around a repeated constant
* expression. The @b 512 is tunable (and no other code needs to
* change), but no investigation has been done since inheriting the
* SGI code. Touch _GLIBCXX_DEQUE_BUF_SIZE only if you know what
* you are doing, however: changing it breaks the binary
* compatibility!!
*/
#ifndef _GLIBCXX_DEQUE_BUF_SIZE
#define _GLIBCXX_DEQUE_BUF_SIZE 512
#endif
inline size_t
__deque_buf_size(size_t __size)
{ return (__size < _GLIBCXX_DEQUE_BUF_SIZE
? size_t(_GLIBCXX_DEQUE_BUF_SIZE / __size) : size_t(1)); }
04 May 2014 » std::string 和引用计数
std::string 又是 STL 中最最最最最最最常用的没有之一的设施。正因为简单,不大被关注。 初用 C++ 的人一定不知道他是从 basic_string 特化出来的,对 C++ 有一定了解的人可能也不知道 string 里面是带引用计数的。现在就来详细剖析一下 string 或者说 basic_string 吧
include/std/string 里面是一堆的 include,就不贴出来浪费篇幅了,有关的是 stringfwd.h,basic_string.h, basic_string.tcc 三个文件。
stringfwd.h
template<class _CharT>
struct char_traits;
template<typename _CharT, typename _Traits = char_traits<_CharT>,
typename _Alloc = allocator<_CharT> >
class basic_string;
template<> struct char_traits<char>;
/// A string of @c char
typedef basic_string<char> string;
#ifdef _GLIBCXX_USE_WCHAR_T
template<> struct char_traits<wchar_t>;
/// A string of @c wchar_t
typedef basic_string<wchar_t> wstring;
#endif
#if ((__cplusplus >= 201103L) \
&& defined(_GLIBCXX_USE_C99_STDINT_TR1))
template<> struct char_traits<char16_t>;
template<> struct char_traits<char32_t>;
/// A string of @c char16_t
typedef basic_string<char16_t> u16string;
/// A string of @c char32_t
typedef basic_string<char32_t> u32string;
03 May 2014 » containers,std::vector
vector 是最最最最最喜闻乐见没有之一的容器了。然后,由于众所周知的原因,略过 vector<bool>
gcc 家的 stl 除了提供了基本的 container,还给了配套的 debug 和 profile 设施。
另外一些算法还提供了 parallel mode。
不过话说回来,感觉 debug mode 和 profile mode 都很积累。debug 报不出行号,内存泄露似乎还是 valgrind 和 tcmalloc 跑起来比较舒服,越界访问直接 gdb 就能定位到行。profile 会给出建议或者性能表现的特性,还是不如直接上 perf 或者 vtune。。。。不过有空还是可以去研究一下内部的原理。
include/bits/vector
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>