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

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 )

(其中GetItemCollType的一个方法)

除了少数几种变化形式外,一直没有成功。更糟糕的是,这些集合是COM智能指针,因此我不确定GetItem是否实际上会被注册为智能指针的成员。

如果有任何关于正确方向的见解,那就太好了,我一直在这个问题上打转。

1个回答

1

如果你总是使用某些特定的COM智能指针来处理棘手的集合(例如_com_ptr_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
  }
}

你的 _com_ptr_t 想法现在对我来说几乎是显而易见的。非常感谢,这解决了问题。 - Bret Kuhns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接