2012-06-22 57 views
4

我有一堆類似COM的集合接口,我試圖編寫類似STL的迭代器。我有迭代器的工作,並專門begin()end()返回我的迭代器。一切都完美無缺!除了當我嘗試使用begin(std::vector)時,它使用我非常普遍的begin()專業化。由於這些COM對象不從基集合對象擴展,我第一次嘗試:C++ 11檢查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

如果你總是使用一些特定的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 
    } 
} 
+0

你'_com_ptr_t'現在的想法,我看到它幾乎是顯而易見的。非常感謝,這個伎倆。 –