我有一堆类似集合的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
是否会实际注册为智能指针的成员。
对正确方向的任何见解都会很棒,我一直在与这个圈子一起跑。
答案 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
}
}