C 11检查成员的COM智能指针

我有一堆类似集合的COM接口,我正在尝试编写类似STL的迭代器.我有迭代器工作和专门的begin()和end()来返回我的迭代器.一切都很完美!除了,当我尝试使用begin(std :: vector)时,它使用了我对begin()的一般特化.由于这些COM对象不是从基本集合对象扩展,我首先尝试:

template< class CollType >
CollectionIterator<CollType> begin( CollType coll )

我明白为什么重载决议没有为std :: vector选择正确的begin(),但我不知道如何解决这个问题.

不幸的是,我没有一个基本集合类来专门化coll参数.我假设我需要像SFINAE这样的东西,只有在合适的成员存在的情况下才能解决这些专业化问题.我试过了:

template<
    class CollType,typename std::enable_if< std::is_member_pointer< decltype(&CollType::GetItem) >::value >::type
>
CollectionIterator<CollType> begin( CollType coll )

(其中GetItem是CollType的方法)

除了一些变化,无济于事.更糟糕的是,这些集合是COM智能指针,所以我不确定GetItem是否会实际注册为智能指针的成员.

对正确方向的任何见解都会很棒,我一直都是围着这个方向跑.

解决方法

如果你总是使用一些特定的COM智能指针来处理棘手的集合(例如_com_ptr_t< T>),你可以用这种方式定义begin()特化:

template<class T> your_iterator_type<T> begin(_com_ptr_t<T>& collection)

如果这是不可接受的,请尝试另一种可能的方式(仅当您使用Visual C并且不关心非标准时) – 使用Microsoft特定扩展 – __if_exists / __ if_not_exists语句:

template<class T> typename T::iterator begin_ex(T& collection)
{
  __if_exists(T::GetItem) {
     return my_collection_begin(collection); // Use custom impl
  }

  __if_not_exists(T::GetItem) {
     return std::begin(collection); // Use standard impl
  }
}

相关文章

首先GDB是类unix系统下一个优秀的调试工具, 当然作为debug代...
1. C语言定义1个数组的时候, 必须同时指定它的长度.例如:int...
C++的auto关键字在C+⬑新标准出来之前基本...
const关键字是用于定义一个不该被改变的对象,它的作用是告诉...
文章浏览阅读315次。之前用C语言编过链表,这几天突然想用C+...
文章浏览阅读219次。碰到问题就要记录下来,防止遗忘吧。文章...