4

STL のような反復子を作成しようとしているコレクションのような COM インターフェイスがたくさんあります。私はイテレータを機能させて特殊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 に答える