4

我有一堆类似集合的 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 )

(哪里GetItem是 的方法CollType

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

任何对正确方向的见解都会很棒,我一直在绕圈子。

4

1 回答 1

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
  }
}
于 2012-08-14T23:42:40.557 回答