返回   cpper编程论坛 > C/CPP/TMP/GP
注册账号 论坛帮助 会员列表 日历事件 搜索 今日新帖 标记版面已读

回复
 
LinkBack 主题工具 显示模式
  #1 (permalink)  
旧 2006-07-06
初级会员
 
注册日期: 2006-06-21
住址: 沪
帖子: 5
Unsigned 正向着好的方向发展
发送 MSN 消息给 Unsigned
默认 谁说C++没有foreach?

#ifndef TCLIB_FOR_EACH_H
#define TCLIB_FOR_EACH_H
//**************************}H{**************************}H{**************************
#ifdef _INC_COMDEF
template<typename CType>
struct GetTypeTrait{
typedef _COM_SMARTPTR<_COM_SMARTPTR_LEVEL2<CType, &__uuidof(CType)> > Type;
typedef CType ** RefType;
};
#else
template<typename CType>
struct GetTypeTrait{
typedef CType Type;
typedef CType * RefType;
};
#endif

#define DEFINE_SIMPLY_GET_TRAIT(type) \
template<>struct GetTypeTrait<type>{ \
typedef type Type; \
typedef type* RefType; \
};
#define DEFINE_CUSTOM_GET_TRAIT(type,ptrType,refType) \
template<>struct GetTypeTrait<type>{ \
typedef ptrType Type; \
typedef refType RefType; \
};

DEFINE_SIMPLY_GET_TRAIT(short);
DEFINE_SIMPLY_GET_TRAIT(long);
DEFINE_SIMPLY_GET_TRAIT(bool);
DEFINE_SIMPLY_GET_TRAIT(double);
DEFINE_SIMPLY_GET_TRAIT(float);
DEFINE_SIMPLY_GET_TRAIT(char);
DEFINE_SIMPLY_GET_TRAIT(UINT);
DEFINE_SIMPLY_GET_TRAIT(ULONG);
DEFINE_SIMPLY_GET_TRAIT(GUID);
#ifdef __ATLBASE_H__
DEFINE_CUSTOM_GET_TRAIT(BSTR,CComBSTR,BSTR*);
DEFINE_CUSTOM_GET_TRAIT(VARIANT,CComVariant,VARIANT*);
#endif
//**************************}H{**************************}H{**************************
//规范各种容器的子对象取值函数
//用几个宏和一个函数子来封装
#define GetI(ConType,foo,i,ItemType,obj) GetFunctor<ConType,ItemType>::GetAtFoo((ConType*)GetTypeTrait<ConType>::Type(obj),i,ConType::foo)
#define GetA(ConType,foo,GetType,obj) GetFunctor<ConType,GetType>::GetFoo((ConType*)GetTypeTrait<ConType>::Type(obj),ConType::foo)
#define NoGet(I,T,f,o) GetFunctor<I,T>::VoidFoo((I*)GetTypeTrait<I>::Type(o),ConType::f)
template<class ObjType,typename GetType,
typename OutRetType = GetTypeTrait<GetType>::Type,
typename InRefType = GetTypeTrait<GetType>::RefType>
struct GetFunctor{
typedef OutRetType RetType;
typedef InRefType RefType;
typedef HRESULT (__stdcall ObjType::* STDCALL_GET_FOO)(RefType);
typedef HRESULT ( ObjType::* CCALL_GET_FOO)(RefType);
typedef HRESULT (__stdcall ObjType::* STDCALL_GETAT_FOO)(long,RefType);
typedef HRESULT ( ObjType::* CCALL_GETAT_FOO)(long,RefType);
typedef HRESULT (__stdcall ObjType::* STDCALL_VOID_FOO)();
typedef HRESULT ( ObjType::* CCALL_VOID_FOO)();
//非COM形式的Get函数
typedef void ( ObjType::* CCALL_SIMPLY_VOID_FOO)(void);
typedef void (__stdcall ObjType::* STDCALL_SIMPLY_VOID_FOO)(void);
typedef OutRetType ( ObjType::* CCALL_SIMPLY_GET_FOO)(void);
typedef OutRetType (__stdcall ObjType::* STDCALL_SIMPLY_GET_FOO)(void);
typedef OutRetType ( ObjType::* CCALL_SIMPLY_GETAT_FOO)(long);
typedef OutRetType (__stdcall ObjType::* STDCALL_SIMPLY_GETAT_FOO)(long);

static bool VoidFoo(ObjType* pObj,STDCALL_VOID_FOO pFun){
if(pObj) return SUCCEEDED((pObj->*pFun)());
return false;
}
static bool VoidFoo(ObjType* pObj,CCALL_VOID_FOO pFun){
if(pObj) return SUCCEEDED((pObj->*pFun)());
return false;
}

static bool VoidFoo(ObjType* pObj,STDCALL_SIMPLY_VOID_FOO pFun){
if(!pObj) return false;
(pObj->*pFun)();
return true;
}
static bool VoidFoo(ObjType* pObj,CCALL_SIMPLY_VOID_FOO pFun){
if(!pObj) return false;
(pObj->*pFun)();
return true;
}

static RetType GetFoo(ObjType* pObj,STDCALL_GET_FOO pFun){
RetType ret(0);
if(pObj) (pObj->*pFun)((RefType) &ret);
return ret;
}
static RetType GetFoo(ObjType* pObj,CCALL_GET_FOO pFun){
RetType ret(0);
if(pObj) (pObj->*pFun)((RefType) &ret);
return ret;
}

static RetType GetFoo(ObjType* pObj,CCALL_SIMPLY_GET_FOO pFun){
return (pObj->*pFun)();
}
static RetType GetFoo(ObjType* pObj,STDCALL_SIMPLY_GET_FOO pFun){
return (pObj->*pFun)();
}

static RetType GetAtFoo(ObjType* pObj,long i,STDCALL_GETAT_FOO pFun){
RetType ret(0);
if(pObj) (pObj->*pFun)(i,(RefType) &ret);
return ret;
}
static RetType GetAtFoo(ObjType* pObj,long i,CCALL_GETAT_FOO pFun){
RetType ret(0);
if(pObj) (pObj->*pFun)(i,(RefType) &ret);
return ret;
}

static RetType GetAtFoo(ObjType* pObj,long i,STDCALL_SIMPLY_GETAT_FOO pFun){
return (pObj->*pFun)(i);
}
static RetType GetAtFoo(ObjType* pObj,long i,CCALL_SIMPLY_GETAT_FOO pFun){
return (pObj->*pFun)(i);
}
};
//**************************}H{**************************}H{**************************
//容器及其子项的类型萃取器
template<typename ConType,typename ItemType>
struct EnumTypesTrait{
typedef GetTypeTrait<ItemType>::Type ITEM_TYPE;
typedef GetTypeTrait<ItemType>::RefType ITEM__REF_TYPE;
typedef GetTypeTrait<ConType>::Type CONTAINER_TYPE;
ITEM_TYPE _item;
protected:
EnumTypesTrait(){ _pObj = 0; }
CONTAINER_TYPE _pObj;
};
//预定义容器概念
//默认为是形如STL的容器
template<class ConType>
struct ContainorConcept{
typedef ConType::value_type ITEM_TYPE;
typedef const ConType CONTAINER_TYPE;
ContainorConcept(const ConType& obj){
_pObj = (&obj);
}
bool Begin(){
if(_pObj->begin() == _pObj->end()) return false;
_iter = const_cast<ConType::iterator>(_pObj->begin());
return true;
}
bool Next(){
if(_iter == _pObj->end()) return false;
_item = *(_iter);
++_iter;
return true;
}
CONTAINER_TYPE * _pObj;
ITEM_TYPE _item;
ConType::iterator _iter;
};
//**************************}H{**************************}H{**************************
//声明容器的枚举方法类型

//将一个容器声明为前向枚举器
#define DECLARE_AS_FORWARD_ENUM(ConType,ItemType,ResetFoo,NextFoo) \
template<>struct ContainorConcept<ConType> : EnumTypesTrait<ConType,ItemType>{ \
ContainorConcept(CONTAINER_TYPE pObj){ \
_pObj = pObj; \
} \
bool Begin(){ \
if(0 == _pObj) return false; \
return NoGet(ConType,ItemType,ResetFoo,_pObj); \
} \
bool Next(){ \
return 0 != (_item = GetA(ConType,NextFoo,ItemType,_pObj));\
} \
};
//将一个容器声明为单次枚举器
#define DECLARE_AS_JUSTONE_ENUM(ConType,ItemType,NextFoo) \
template<>struct ContainorConcept<ConType> : EnumTypesTrait<ConType,ItemType>{ \
ContainorConcept(CONTAINER_TYPE pObj){ \
_pObj = pObj; \
} \
bool Begin(){ \
return 0 != _pObj; \
} \
bool Next(){ \
return 0 != (_item = GetA(ConType,NextFoo,ItemType,_pObj));\
} \
};
//申明一个为随即枚举器
#define DDECLARE_AS_RANDOM_ENUM(ConType,ItemType,CountFoo,GetAtFoo) \
template<>struct ContainorConcept<ConType> : EnumTypesTrait<ConType,ItemType>{ \
ContainorConcept(CONTAINER_TYPE pObj){ \
_pObj = pObj; \
nCount = 0;i = 0; \
} \
long nCount,i; \
bool Begin(){ \
return 0 != (nCount = GetA(ConType,CountFoo,long,_pObj)); \
} \
bool Next(){ \
if(i >= nCount) return false; \
return 0 != (_item = GetI(ConType,GetAtFoo,i++,ItemType,_pObj)); \
} \
};
//**************************}H{**************************}H{**************************
#define _for_each(ConType,container,item) \
{ContainorConcept< ConType > ConCpt(container); \
ContainorConcept< ConType >::ITEM_TYPE item; \
if(ConCpt.Begin()) \
while(ConCpt.Next()){ \
item = ConCpt._item;
#define _end_for_each }}

//**************************}H{**************************}H{**************************
DECLARE_AS_JUSTONE_ENUM(ICursor,IRow,NextRow);

DDECLARE_AS_RANDOM_ENUM(IArray,IUnknown,get_Count,get_Element);
DDECLARE_AS_RANDOM_ENUM(ILongArray,long,get_Count,get_Element);

/*
#include "UnitTest.h"

struct MyFWDContainer
{
void Reset(){ a = 100;};
long Next(){ return --a;};
long a;
};
DEFINE_CUSTOM_GET_TRAIT(MyFWDContainer,MyFWDContainer*,MyFWDContainer**);
DECLARE_AS_FORWARD_ENUM(MyFWDContainer,long,Reset,Next);

_beg_utest(3,"MyFWDContainer UTest")
MyFWDContainer a;
_for_each(MyFWDContainer,&a,i)
_end_for_each
_end_utest

_beg_utest(0,"COM Interface UTest")
IArrayPtr pArr(CLSID_Array);
pArr->Insert(0,(IUnknown*)pArr);
pArr->Insert(1,(IUnknown*)pArr);
pArr->Insert(2,(IUnknown*)pArr);
_for_each(IArray,pArr,pSelf)
SAY(----------------);
_for_each(IArray,pSelf,pUnk)
SAY2(((long)((void*)((IUnknown*)pUnk))));
_end_for_each
_end_for_each
_end_utest

_beg_utest(1,"STD Container UTest")
typedef std::vector<long> LONGARR;
LONGARR LonArr;
LonArr.push_back(0);
LonArr.push_back(1);
LonArr.push_back(2);
_for_each(LONGARR,LonArr,i)
SAY2(i);
_end_for_each
_end_utest
_beg_utest(2,"STD String UTest")
std::string a("Hello for each!");
_for_each(std::string,a,ch)
SAY2(ch);
_end_for_each
_end_utest
*/
#endif
/*

*/
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #2 (permalink)  
旧 2006-07-07
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,138
文章: 20
polyrandom 正向着好的方向发展
默认

可是这样用起来很不爽,没有vb之类的语言那么直观。这样的for_each和for(iter=begin; iter != end; ++iter)相比,我还是宁可用后者。毕竟形式上已经差不多复杂了,还不用依赖这一堆template和macro。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #3 (permalink)  
旧 2006-07-07
初级会员
 
注册日期: 2006-06-21
住址: 沪
帖子: 5
Unsigned 正向着好的方向发展
发送 MSN 消息给 Unsigned
默认

主要是在VC里遍历COM的容器接口时感觉很罗嗦总是要
IItemPtr i;
ipEnum->Reset();
ipEnum->Next(&i);
while(i)
{
//........
ipEnum->Next(&i);
};
或者
long nCount = 0;
IUnknownPtr ipUnk;
ipArr->get_Count(&nCount);
for(long k = 0;k < nCount; ++k)
{
//....
ipArr->get_Element(k,&ipUnk);
//....
}
就写了这些,以后就可以这样了
_for_each(IEnumerator,ipEnum,i)
//....Do(i);
_end_for_each

_for_each(IArray,ipArr,ipUnk)
//...Do(ipUnk);
_end_for_each
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #4 (permalink)  
旧 2006-07-07
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,138
文章: 20
polyrandom 正向着好的方向发展
默认

这个稍微封装以下,变成:
代码:
Enum enum( ipEnum ); while( enum ) { do_sth( enum.get() ); ++enum; } Enum enum( ipArr ); while( enum ) { ipUnk = enum.get(); .... ++enum; }
这样就干净很多了。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #5 (permalink)  
旧 2006-07-07
初级会员
 
注册日期: 2006-06-21
住址: 沪
帖子: 5
Unsigned 正向着好的方向发展
发送 MSN 消息给 Unsigned
默认

这样也可以......
不过,对于每使用一个新容器类型都要重写重载Enum()和operator bool好像不太合算
并且Get()采用基于返回值的重载也会导致左值构造的歧义
而_for_each的方式就简单些了:~)
DDECLARE_AS_XXX_ENUM(INewContainer,INewItem,BeginFoo,GetFoo);
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #6 (permalink)  
旧 2006-07-07
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,138
文章: 20
polyrandom 正向着好的方向发展
默认

这个用template加上uuidof,是不是可以简便很多?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #7 (permalink)  
旧 2006-07-07
初级会员
 
注册日期: 2006-06-21
住址: 沪
帖子: 5
Unsigned 正向着好的方向发展
发送 MSN 消息给 Unsigned
默认

最大的希望还是能提供一个较为统一的遍历方式,不仅是COM接口,还有stl容器、MFC容器以及自定义的各种容器类
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #8 (permalink)  
旧 2006-07-07
Innocentius 的头像
版主
 
注册日期: 2002-09-11
住址: 上海
帖子: 562
文章: 12
Innocentius 正向着好的方向发展
发送 MSN 消息给 Innocentius
默认

我也有一个for_each实现,用法和你的差不多,不过实现方法有些不一样。Boost里面用法更加简单,但是实现相当复杂……

我觉得还是有必要实现一个 for_each,特别是用惯了 C# 里面的 foreach 以后……
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #9 (permalink)  
旧 2006-07-07
高级会员
 
注册日期: 2002-09-16
帖子: 1,087
文章: 1
SpitFire 正向着好的方向发展
默认

看来语法糖衣还是很重要滴

over
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #10 (permalink)  
旧 2006-07-08
初级会员
 
注册日期: 2006-06-21
住址: 沪
帖子: 5
Unsigned 正向着好的方向发展
发送 MSN 消息给 Unsigned
默认

引用:
作者: Innocentius
我也有一个for_each实现,用法和你的差不多,不过实现方法有些不一样。Boost里面用法更加简单,但是实现相当复杂……

我觉得还是有必要实现一个 for_each,特别是用惯了 C# 里面的 foreach 以后……
能否不吝贴来共赏?:~)
这个_for_each是在VC6下实现的(它对泛型的支持太弱了),所以用了太多的Macro,不构grace。希望能够讨论出一个比较完美的方式来....
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #11 (permalink)  
旧 2006-07-08
Innocentius 的头像
版主
 
注册日期: 2002-09-11
住址: 上海
帖子: 562
文章: 12
Innocentius 正向着好的方向发展
发送 MSN 消息给 Innocentius
默认

我实现的foreach仿造.NET中迭代的做法,也就是定义了一个IEnumerable接口,对于不支持这个结构的类型,则通过代理来完成。代码如下:
代码:
#if !defined(__NENUMERATOR_H) || !defined(__NENUMERATOR_H_0F9A6763_0891_4710_9DE2_2E7915D7741C_INCLUDED) #define __NENUMERATOR_H_0F9A6763_0891_4710_9DE2_2E7915D7741C_INCLUDED #define __NENUMERATOR_H "{0F9A6763-0891-4710-9DE2-2E7915D7741C}" namespace Abacl { //=============================================================================================== // Name: // // template<T> struct IEnumerable; // // Purpose: // // 作为可枚举(可遍历)对象的接口定义。 // //----------------------------------------------------------------------------------------------- template<typename T> struct IEnumerable { //======================================================================================= // Name: // // typedef ValueType; // // Purpose: // // 遍历的目标元素类型。 // //--------------------------------------------------------------------------------------- typedef T ValueType; // // 虚析构函数 // virtual ~IEnumerable() { } //======================================================================================= // Name: // // ValueType & Current(); // // Purpose: // // 返回当前遍历的目标元素 // // Returns: // // 返回当前遍历的目标元素引用。 // // Remarks: // // 该函数不是 const 成员函数,因此在实现此函数时可能需要进行转型。 // //--------------------------------------------------------------------------------------- virtual ValueType & Current() = 0; //======================================================================================= // Name: // // bool IsValid(); // // Purpose: // // 判断当前遍历位置是否有效。 // // Returns: // // 返回 true 表明当前遍历位置有效,可以调用 Current,否则表明位置无效,不能调用 Current。 // //--------------------------------------------------------------------------------------- virtual bool IsValid() const = 0; //======================================================================================= // Name: // // bool MoveNext(); // // Purpose: // // 移动到下一个遍历位置。 // // Returns: // // 返回 true 表明当前遍历位置有效,可以调用 Current,否则表明位置无效,不能调用 Current。 // //--------------------------------------------------------------------------------------- virtual bool MoveNext() = 0; //======================================================================================= // Name: // // bool Reset(); // // Purpose: // // 将当前遍历位置恢复为起始位置。 // // Returns: // // 返回 true 表明当前遍历位置有效,可以调用 Current,否则表明位置无效,不能调用 Current。 // // Remarks: // // 对于某些对象,该操作可能不能进行。 // //--------------------------------------------------------------------------------------- virtual bool Reset() = 0; }; //=============================================================================================== // Name: // // template<typename T> class DefaultEnumeratorProxy; // // Purpose: // // 代理未实现 IEnumerable 接口的对象。实现 IEnumerable 接口的对象可以应用 foreach 和 foreach_n // 宏来实现遍历。 // // Template Parameters: // // T 需要代理的源对象 // // Remarks: // // 通过类特化和偏特化,实现了下列对象的代理: // // STL 容器 所有 STL 容器均可以通过 DefaultEnumeratorProxy 代理 // 数组 所有对象的数组均可以通过 DefaultEnumeratorProxy 代理,但是必须能获取数组元 // 素数,亦即,不能是 T a[] 形式的数组,而必须是 T a[N] 形式的数组 // 指针 所有对象的指针均可以通过 DefaultEnumeratorProxy 代理,但是 foreach 只能正确迭代 // 字符指针,因为如果不指定元素大小,DefaultEnumeratorProxy 只能通过检查元素值 // 是否为 0 来判断是否迭代结束。对于任意类型的对象指针,应当使用 foreach_n // 遍历。 // // 对于未支持的类型,将会出现编译错误。 // //----------------------------------------------------------------------------------------------- // // 泛化版本,用于所有 STL 容器(或者支持 STL 容器接口的类型) // template<typename containerT> class DefaultEnumeratorProxy: public IEnumerable<typename IsTypeConst<typename containerT::value_type>::NonConstType> { typedef containerT ContainerType; typedef typename IfThenElse<IsTypeConst<ContainerType>::Yes, typename ContainerType::const_iterator, typename ContainerType::iterator>::ResultType IteratorType; typedef typename IsTypeConst<typename containerT::value_type>::NonConstType ValueType; private: mutable ContainerType & mContainer; IteratorType mIterator; private: DefaultEnumeratorProxy(); DefaultEnumeratorProxy(const DefaultEnumeratorProxy & rhs); DefaultEnumeratorProxy & operator = (const DefaultEnumeratorProxy & rhs); public: DefaultEnumeratorProxy(ContainerType & container) : mContainer(container), mIterator(container.begin()) { } virtual ValueType & Current() { return const_cast<ValueType &>(*mIterator); } virtual bool IsValid() const { return mIterator != mContainer.end(); } virtual bool MoveNext() { if (IsValid()) { ++mIterator; } return IsValid(); } virtual bool Reset() { mIterator = mContainer.begin(); return IsValid(); } }; // // 对指针的特化版本 // template<typename T> class DefaultEnumeratorProxy<T *>: public IEnumerable<typename IsTypeConst<T>::NonConstType> { typedef T * ContainerType; typedef SizeType IteratorType; typedef typename IsTypeConst<T>::NonConstType ValueType; private: ContainerType mContainer; IteratorType mIterator; const SizeType mCount; private: DefaultEnumeratorProxy(); DefaultEnumeratorProxy(const DefaultEnumeratorProxy & rhs); DefaultEnumeratorProxy & operator = (const DefaultEnumeratorProxy & rhs); public: DefaultEnumeratorProxy(ContainerType container, SizeType count = 0) : mContainer(container), mIterator(0), mCount(count) { } virtual ValueType & Current() { return const_cast<ValueType &>(mContainer[mIterator]); } virtual bool IsValid() const { if (mCount == 0) { return mContainer[mIterator] != ValueType(); } else { return mIterator < mCount; } } virtual bool MoveNext() { if (IsValid()) { ++mIterator; } return IsValid(); } virtual bool Reset() { mIterator = 0; return IsValid(); } }; // // 对数组的特化版本。 // 注:形如 T a[] 形式的数组被认为是指针。 // template<typename T, size_t N> class DefaultEnumeratorProxy<T [N]>: public CustomizedNewObject<AbaclFastAllocator>, public IEnumerable<typename IsTypeConst<T>::NonConstType> { typedef T ContainerType[N]; typedef size_t IteratorType; typedef typename IsTypeConst<T>::NonConstType ValueType; private: ContainerType& mContainer; IteratorType mIterator; private: DefaultEnumeratorProxy(); DefaultEnumeratorProxy(const DefaultEnumeratorProxy & rhs); DefaultEnumeratorProxy & operator = (const DefaultEnumeratorProxy & rhs); public: DefaultEnumeratorProxy(ContainerType & container) : mContainer(container), mIterator(0) { } virtual ValueType & Current() { return mContainer[mIterator]; } virtual bool IsValid() const { return mIterator < N; } virtual bool MoveNext() { if (IsValid()) { ++mIterator; } return IsValid(); } virtual bool Reset() { mIterator = 0; return IsValid(); } }; //=========================================================================================== // Name: // // template<U, T, bool NeedProxy> struct ForEachCreateEnumerator; // // Purpose: // // 如果类型 U 没有实现 IEnumerable 接口,则创建创建代理对象,否则仅返回 IEnumerable // // Template Parameters // // U 容器对象,可以是实现了 IEnumerable 接口,也可以没有实现。如果没有实现 // 则会创建一个代理对象。 // T 遍历对象的元素类型 // NeedProxy 非类型参数,如果为 true,表明 U 没有实现 IEnumerable 接口,需要代理, // 否则就不需要代理 // // Remarks: // // 调用 Create 函数创建。 // //------------------------------------------------------------------------------------------- template<typename U, typename T, bool NeedProxy = IsTypeDerivedFrom<U, IEnumerable<T> >::Yes != 0> struct ForEachCreateEnumerator; template<typename U, typename T> struct ForEachCreateEnumerator<U, T, true> { static IEnumerable<T> * Create(IEnumerable<T> & enumerator) { return &enumerator; } static IEnumerable<T> * Create(IEnumerable<T> & enumerator, SizeType /*count*/) { return &enumerator; } }; template<typename U, typename T> struct ForEachCreateEnumerator<U, T, false> { static IEnumerable<T> * Create(U & enumerator) { return new DefaultEnumeratorProxy<U>(enumerator); } static IEnumerable<T> * Create(U & enumerator, SizeType count) { return new DefaultEnumeratorProxy<U>(enumerator, count); } }; //=========================================================================================== // Name: // // template<typename T> class ForEachEnumerator; // // Purpose: // // 用于 foreach 和 foreach_n 的枚举代理。 // //------------------------------------------------------------------------------------------- template<typename T> class ForEachEnumerator { private: bool mOwn; IEnumerable<T> * mEnumerator; public: template<typename U> explicit ForEachEnumerator(U & enumerator) : mOwn(IsTypeDerivedFrom<U, IEnumerable<T> >::No != 0), mEnumerator(ForEachCreateEnumerator<U, T>::Create(enumerator)) { } template<typename U> explicit ForEachEnumerator(U & enumerator, SizeType count) : mOwn(IsTypeDerivedFrom<U, IEnumerable<T> >::No != 0), mEnumerator(ForEachCreateEnumerator<U, T>::Create(enumerator, count)) { } ~ForEachEnumerator() { if (mOwn) { delete mEnumerator; } } operator T & () { return mEnumerator->Current(); } bool IsValid() const { return mEnumerator->IsValid(); } bool MoveNext() { return mEnumerator->MoveNext(); } }; //=============================================================================================== // Name: // // foreach(value_type, iterator, container) // foreach_n(value_type, iterator, container, n) // // Purpose: // // 对实现 IEnumerable 接口的对象进行遍历,对于部分未实现 IEnumerable 接口的类型进行包装后 // 遍历。 // // 对于非字符类型的指针,使用 foreach_n 遍历。 // // Parameters: // // value_type 遍历的元素类型 // iterator 遍历的迭代器名称 // container 遍历的容器名称 // n 对于指针类型,遍历的元素个数 // //----------------------------------------------------------------------------------------------- #define foreach(value_type, iterator, container) \ for (Abacl::ForEachEnumerator<value_type> iterator(container); iterator.IsValid(); iterator.MoveNext()) #define foreach_n(value_type, iterator, container, n) \ for (Abacl::ForEachEnumerator<value_type> iterator(container, n); iterator.IsValid(); iterator.MoveNext()) } #endif // if !defined(__NENUMERATOR_H_0F9A6763_0891_4710_9DE2_2E7915D7741C_INCLUDED)
其中用到了一些模板类用来判断类型信息,包括:

IsTypeConst<T>:判断一个类型是否是const类型,并且IsTypeConst<T>::NonConstType是这个类型的非const类型。
IfThenElse<bool c, T1, T2>:如果c为true,那么IfThenElse::ResultType 为T1,否则为T2。
IsTypeDerivedFrom<U, T>:判断U是否从T派生。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #12 (permalink)  
旧 2006-07-09
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认

能不能支持return yield?那样就贼爽了。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #13 (permalink)  
旧 2006-07-09
Innocentius 的头像
版主
 
注册日期: 2002-09-11
住址: 上海
帖子: 562
文章: 12
Innocentius 正向着好的方向发展
发送 MSN 消息给 Innocentius
默认

retrun yield 要跨越函数边界,没有编译器支持恐怕有点困难。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #14 (permalink)  
旧 2006-07-12
初级会员
 
注册日期: 2006-02-13
帖子: 22
imported_fixopen 正向着好的方向发展
默认

别说return yield,就连并行现在的C++都没有考虑过。Python现在还不支持return yield呢。
return yield也就是对协程有用,可是协程是否能够完整地表达所有的并行么?我表示怀疑。
看了Sutter关于C++命运的ppt,觉的C++社区和供应商现在对于C++并行方面的考虑非常的深入,提供了active,future等特性,在非常高的层面表达并行了。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
回复

书签

主题工具
显示模式

发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛启用 表情符号
论坛启用 [IMG] 代码
论坛禁用 HTML 代码
Trackbacks are 启用
Pingbacks are 启用
Refbacks are 启用



所有时间均为格林尼治时间 +9。现在的时间是 08:43 AM


Powered by vBulletin® 版本 3.7.0
版权所有 ©2000 - 2009,Jelsoft Enterprises Ltd.
(C) Copy Right All Right Reserved 2001 - 2007

Search Engine Friendly URLs by vBSEO 3.1.0