2012-04-17 9 views
3

は、任意のサイズのアレイを取るコードを書くことは非常に簡単です:std :: array iteratorテンプレートなしの範囲ですか? Cアレイと

void func(T* itBegin, T* itEnd); 

void main() { 
    T arr1[1]; 
    func(std::begin(arr1), std::end(arr1)); 
    T arr2[2]; 
    func(std::begin(arr2), std::end(arr2)); 
} 

にはどうすればいいのstd ::アレイとすることを行うことができますか?

void func(??? itBegin, ??? itEnd); 

void main() { 
    std::array<T,1> arr1; 
    func(std::begin(arr1), std::end(arr1)); 
    std::array<T,2> arr2; 
    func(std::begin(arr2), std::end(arr2)); 
} 

問題はMSVC 2010年には、std::array<T,N>::iteratorが異なるNのために異なっている、ということです。これはMSVC 2010のバグですか?そうでない場合、このデザインの根拠は何ですか?はい、私はstd :: arrayからポインタを取得し、イテレータの代わりにそれらを渡すことができますが、それは不必要に醜いものではありませんか?

BTW、boost::array<T,N>::iteratorはすべてNで同じです。

+0

「テンプレートなし」とはどういう意味ですか? – juanchopanza

+0

'void func(T * itBegin、T * itEnd)'はすでにテンプレート化された関数なので、 "テンプレートなし"の要件にどう対応することができません。 – Gorpik

+0

@Gorpik:まあ、いいえ、テンプレート化されていません。それはちょうど 'T'という不幸な名前のタイプを使用します。 'main'も参照してください。' main'も 'T'を使用しており、テンプレート化することはできません。 – MSalters

答えて

4
template <class I> 
void func(I begin, I end) 
{ 
    for (auto x = begin; x != end; ++x) 
     something_with(*x); 
} 

タイプパラメータとして汎用的に定義し、ポインタとして使用します。ポインタのように動作するものはコンパイルされ、コンパイルされないものはコンパイルされません。

ポインタのようなものには、通常のポインタ、標準ライブラリイテレータ、operator=operator*、およびoperator++を定義するものが含まれます。

このようにそれを行うと、あなただけの今までに開始/終了イテレータの一致するペアを使用しますと、同じarray<N>の範囲array<N>::iteratorarray<M>::iteratorに異なるタイプであれば、それは問題ではありません。

+0

テンプレートがあれば簡単だと分かっています。しかし、仮想関数は、例えば、テンプレートとすることはできず、テンプレート内にテンプレートを定義する必要があります。テンプレートが必要な技術的理由はありません。 – Arno

+1

@Arno:型パラメータは、イテレータを渡すためのC++イディオムです。あなたがテンプレートに慣れていないなら、あなたは標準ライブラリを使って悲惨になるでしょう。 –

0
template <class I> 
void func(I begin, I end); 
2

私の知る限り、標準は、異なるサイズのstd::arrayは、イテレータの同じ型を持っていることを必要としません。 std::array<int, 1>std::array<int, 2>の異なるタイプのものは合法的です(ただし、実装の質に関していくつかの意見があります)。

これが問題である場合は、Cスタイルの配列、または使用ポインタを使用することができ、次のいずれか

func(&arr1[0], &arr1[0] + arr1.size()); 

どちらのソリューションが理想的ですが、彼らは私が提供できる最高です。

+0

'&* begin(arr1)、&* end(arr1)'?最初の一見で奇妙に見えるかもしれませんが、イテレータ、スマートポインタを持つ一般的なテクニックでなければなりません。 – visitor

+0

これは、基本となるメモリブロックが連続してコンパクトな場合にのみ機能します。これは、配列とベクトル用ですが、一般的ではありません。 – Arno

+0

@Arno:答えに長い構文も必要です。 – UncleBens

関連する問題