2016-04-12 9 views
1

基本型を制限するイテレータをどのように作成しますか?例えば、私は次のような関数を作成したい:特定の型へのC++イテレータ

void functionThatOperatesOnPointSequence(PointIterator begin, PointIterator end); 
Pointオブジェクトの配列が、異なる方法で格納することができる

。私のユースケースは、Pointがテンプレート化されたタイプになるという複雑さが増します。すなわちPoint<int>またはPoint<double>も同様に有効です。

C++ 11/14またはBoostを使用するソリューションは有効であり、望ましいものです。

+1

あなたは何かを作成しましたか?それはスタックのオーバーフローなので、あなたは何らかの努力をしたということを質問する必要があります。準備が整った解決策を求めないでください。 – sebap123

+0

'PointIterator :: operator *'は、1種類のオブジェクトだけを返すことができます。 'PointIterator'はおそらくテンプレートの引数でなければなりません。 – user2079303

+1

is_a_point > :: value'? – Jarod42

答えて

0

ここでは、テンプレートメタプログラミングのビットです。 is_template_instanceは、型と型を取るテンプレートをとり、その第2型が最初のテンプレートのインスタンスであれば真を返します。

template<template<class...>class Z, class T> 
struct is_template_instance:std::false_type{}; 
template<template<class...>class Z, class...Ts> 
struct is_template_instance<Z,Z<Ts...>>:std::true_type{}; 

ここで、イテレータの値の型を照会する必要があります。 is_point_iteratorテンプレートの書き込みに私たちは、上記の2を構成

template<class It> 
using it_value_type = typename std::iterator_traits<It>::value_type; 

::私たちは、直接std::iterator_traitsを使用するか、またはこのようなエイリアスを使用することができます

template<class It> 
using is_point_iterator = is_template_instance< Point, it_value_type<It> >; 

注意をあなたはこの非イテレータを渡した場合、それはかもしれないことまたは、間違った結果を返す可能性があります(std::iterator_traitsは、イテレータ以外の場合の合理的な戻り値を保証しません)。

しかし、それはテンプレート本体で捕捉される傾向があります。

template<class PointIterator, 
    class=std::enable_if_t< is_point_iterator<PointIterator>::value > 
> 
void functionThatOperatesOnPointSequence(PointIterator begin, PointIterator end) { 
    // ... 
} 

有用性には限りがあります。

次の例のように、より多くのSFINAEに優しい方法でPointIteratorからの値型を抽出できます。

template<class It> 
using it_value_type = std::decay_t<decltype(*std::declval<It>())>; 

あなたはSFINAEのサポートが必要な場合。

+0

'Point 'の派生クラスが 'Point'とみなされるべきかどうかという疑問もあります。 (あなたの場合は現在)。 – Jarod42

+0

@ Jarod42 'Point 'から派生した型と 'operator Point &()'を持つ型を区別しない簡単な解決法(関数オーバーロードに基づく)を考えることができます。おそらく私は 'is_iterator_over 'にリファクタリングして、それをより使いやすくする必要があります。 – Yakk

関連する問題