能力值:
( LV9,RANK:170 )
|
-
-
2 楼
谢谢 NeverGone ,已下载《Modern C++ design》和loki,正在学习
这便是讨论的收获。
第二章 尝试支持数组
废话不多说,请看附件 2.cpp ,这里用define 实现了基本的 FOR_EACH,
#define FOR_EACH2(VAR, COL) \
auto_any_t _cur = BAIL::begin11( COL ); \
auto_any_t _end = BAIL::end11( COL ); \
for (bool _conti = true; \
_conti && !BAIL::done1( _cur, _end, COL); \
_conti ? BAIL::next1( _cur, COL) : (void)0) \
{ _conti = false; \
for (VAR = BAIL::deref1(_cur, COL); !_conti; _conti = true)
void test()
{
int tbl[] = {1,2,3,4,5,6};
FOR_EACH2( int i, tbl )
{
std::cout << i << ' ';
}}
}
说明几点:
* 因为FOR_EACH后面是一个{},显示不可能定义为一个template或函数,只能是define
* FOR_EACH的第一个参数是 int i,如果写成通常的for,那么怎么写 i++ 呢?显然
做不到。不得已只好用双for,每次都给int i 赋值
* 加了个 _conti有两个用途,一是 inti 所在的for只能允许它运行一次。二是当它
break时上一个for也能知道并退出。就这么复杂了
* 我们可以写一个begin11的模板,返回一个 iterator1<T>::type 的数据类型。但一
旦从模板出来,用什么样的数据类型去保存它呢?boost的做法,是转为 auto_any<T>,
然后存到一个 auto_any_t 中,使用的时候用 auto_any_cast 可以转化回来。这个过程
我至今还没有理解。
最后,用这个方法写出来的 FOR_EACH 有两个缺点,一是前面不能加if,它虽然看起来是一行,
实际却是多行。二是后面必须多写一个 } 号。因为用了双层的 for
你知道怎么解决这两个问题吗?请看下一章
|
能力值:
( LV9,RANK:170 )
|
-
-
3 楼
第三章 尝试支持数组之二
为了解决上一章提到的两个问题,增加一个set_false函数
inline bool set_false(bool &b)
{
b = false;
return false;
}
使用了一个技巧:
if (int i = 0) {} else
见附件 3.cpp 至此已经完全支持数组了:
void test()
{
int tbl[] = {1,2,3,4,5,6,7};
FOR_EACH( int i, tbl )
{
std::cout << i << ' ';
}
}
且支持 break, continue, 前if
接下来,尝试增加对 std:list, "hello"的支持
|
能力值:
( LV9,RANK:170 )
|
-
-
4 楼
第四章 支持std:list
稍作修改,支持 std:list, std:vector, std:deque
void test()
{
std::vector<int> m;
m.push_back(10);
m.push_back(20);
m.push_back(30);
FOR_EACH( int i, m )
{
std::cout << i << ' ';
}
}
接下来,尝试增加对 "hello"的支持
|
能力值:
( LV9,RANK:170 )
|
-
-
5 楼
第五章 支持C++字串
继续修改,支持 null-terminated C-style strings,最后,我们的宏支持所有以下情况:
void test()
{
int tbl[] = {1,2,3,4,5,6,7};
if (1)
FOR_EACH( int i, tbl )
{
std::cout << i << ' ';
}
std::cout << std::endl;
std::vector<int> m; // also support std::list, std::deque
m.push_back(10);
m.push_back(20);
m.push_back(30);
FOR_EACH( int i, m )
{
std::cout << i << ' ';
}
std::cout << std::endl;
const char * hello = "hello, world\n";
FOR_EACH( char ch, hello )
{
std::cout << ch;
}
}
代码见附件,不知道还能不能更简单地实现。
关注的人太少了,不再更新....
|
能力值:
( LV8,RANK:130 )
|
-
-
6 楼
Template Metaprogramming, 更多像智力玩具
template< bool C_ > struct bool_
{
enum { value = C_ };
};
typedef bool_<true> true_;
typedef bool_<false> false_;
类似这种代码,利用模版特化萃取类型信息,SGI STL源码里到处都是。
LiuTaoTao这么有兴趣,可以看看《Modern C++ design》
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
字符和容器可以实现,但是数组自动计算大小搞不定
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
呵呵,每个人知识面不同,原来LZ精力和研究方向主要是汇编,现在突然接触比较有技巧的C++模板有感慨是很正常的。
要鼓励分享这种渐进的学习日记。
|
能力值:
( LV12,RANK:270 )
|
-
-
9 楼
刚看了那道题,被虐了。表示一直用的C,对模板神马的一窍不通……
|
能力值:
( LV15,RANK:670 )
|
-
-
10 楼
跟着涛哥走.
#include <iostream>
// 定义一个名为 bool_ 的模板类
// 只有一个枚举类型的成员 value
template< bool C_ > struct bool_
{
enum { value = C_ };
};
// 定义两个类型, 当使用时编译器会将其特例化为具体的类
typedef bool_<true> true_;
typedef bool_<false> false_;
// 定义另一个模板类 is_array ,派生于 false_ , 这是 is_array 的普通版本
// 只有在特例化请求不符合以下的所有情况时,编译器才将其与普通版本相匹配
template< typename T > struct is_array : false_ { }; /* 版本A */
// is_array 的局部特例化版本,派生于 true_ , 对应的特例化请求是 char[1], int[2], double[3]...
template< typename T, int N > struct is_array< T[N] > /* 版本B */
: true_
{
};
// is_array 的局部特例化版本,派生于 true_ , 对应的特例化请求是 char const [1], int const [2], double const [3]...
template< typename T, int N > struct is_array< T const[N] > /* 版本C */
: true_
{
};
// is_array 的局部特例化版本,派生于 true_ , 对应的特例化请求是 char[], int[], double[]...
template< typename T > struct is_array< T[] > /* 版本D */
: true_
{
};
// is_array 的局部特例化版本,派生于 true_ , 对应的特例化请求是 char const [], int const [], double const []...
template< typename T > struct is_array< T const[] > /* 版本E */
: true_
{
};
// vc6 不支持模板偏特化(也叫局部特例化或部份特例化)
// 需要使用 vc7.1 或以上的编译器
int _tmain(int argc, _TCHAR* argv[])
{
if(is_array<int>::value == false) /* 使用版本A */
std::cerr << "int test ok" << std::endl;
if(is_array<int*>::value == false) /* 使用版本A */
std::cerr << "int* test ok" << std::endl;
if(is_array<int[]>::value == true) /* 使用版本D */
std::cerr << "int[] test ok" << std::endl;
if(is_array<int[2]>::value == true)/* 使用版本B */
std::cerr << "int[2] test ok" << std::endl;
if(is_array<const int[2]>::value == true) /* 使用版本B */
std::cerr << "const int[2] test ok" << std::endl;
if(is_array<int const [2]>::value == true) /* 使用版本E */
std::cerr << "int const [2] test ok" << std::endl;
return 0;
}
|
能力值:
( LV3,RANK:20 )
|
-
-
11 楼
看着这些代码,我好纠结
|
能力值:
( LV15,RANK:670 )
|
-
-
12 楼
俗话说:女为悦已者容。
|
能力值:
( LV12,RANK:470 )
|
-
-
13 楼
虽然看不懂,进来支持1下涛哥
|
能力值:
( LV10,RANK:170 )
|
-
-
14 楼
每看一次涛哥的贴子都是一次进步,支持一下~
|
能力值:
( LV11,RANK:188 )
|
-
-
15 楼
学习cntrump,支持涛哥.
 刚看完第一楼,看到[n]来区分是否为数组就高兴的在注释的,才发现cntrump大侠先下手为强了。
回帖支持!
|
能力值:
( LV12,RANK:385 )
|
-
-
16 楼
其实我也挺喜欢C++的模板的。
标记,供以后学习,现在不知怎吗的还没有心情去学习这个。
|
|
|