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

时间:2012-06-22 12:28:41

标签: c++ com c++11 sfinae

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

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

我知道为什么重载决策没有为begin()选择正确的std::vector,但我不知道如何解决此问题。

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

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

(其中GetItemCollType的方法)

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

对正确方向的任何见解都会很棒,我一直在与这个圈子一起跑。

1 个答案:

答案 0 :(得分:1)

如果您总是使用某些特定的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
  }
}