2015-12-30 15 views
6

簡単な質問です。なぜstd :: copy_nはstd :: size_tではなくテンプレートパラメータを取るのですか?

template<class InputIt, class Size, class OutputIt> 
OutputIt copy_n(InputIt first, Size count, OutputIt result); 

なぜstd::copy_nは、単にstd::size_tのコピーの代わりになるだろう要素の数の種類を取るのでしょうか?私は理由を考えることができません。オリジナルの根拠について推測

template<class InputIt, class OutputIt> 
OutputIt copy_n(InputIt first, std::size_t count, OutputIt result); 
+1

もしcountが 'std :: size_t'ならば、関数がパラメータcountが' signed int'で負の値を持つ関数を突然呼び出すと、積分プロモーションが行われます。未定義の動作。 – Danh

+2

明らかなケースは、必要なサイズが 'size_t'の最大値よりも大きくなる可能性がある場合です。 –

答えて

6

は、このような場合にはほとんど無益であるが、この設計でcopy_nは、例えば、負の数で起動することができますintまたはptrdiff_tタイプです。その場合は、単に何もしません。それは、かなり有能な人である標準化委員会のメンバーには明らかであるはずです。


1つの追加の利点は、入力と出力イテレータのような特別なイテレータと、大きさは任意の可能なポインタの差よりも大きい場合があり、したがっておそらくはより大きいsize_tを表すことができることです。例えば。これは、32ビットWindowsで4GBを超えるファイルの場合と同様です。 の定義は、明示的なポインタ/イテレータ演算で表されます。“各非負整数i < nに対しては、*(result + i) = *(first + i) ”を実行します。この利点は非常に特殊なケースになりますが、表記法は純粋な入力および出力イテレータアルゴリズムオペレータ+-の説明で

それらがあることを持っていない ためイテレータカテゴリの一部に使用される:

C++ 11§25.1/ 12で説明したように定義された。これらの場合に a+nのセマンティクスは

X tmp = a; 
advance(tmp, n); 
return tmp; 
b-a

とのそれはreturn distance(a, b)のと同じであるのと同じです。


設計の汎用性ではなく、それ自体が欠点は、より冗長だとそれほど簡単に生成し、誤った使用コードの診断を理解していることであります、何の固有の利点を持っていません。その利点には、上記の2つの利点があります。明らかに、委員会は、これらの利点、およびおそらく他のもの(?)がSizeをテンプレートパラメータとして持つという固有の欠点を上回っていると感じました。

+0

符号なし整数型で呼び出されない限り、振る舞いは未定義と指定されている可能性があります。なぜなら、std :: copy_nの考え方は、n個の要素をコピーすることだからです。我々はいくつかの要素を扱っているので、負であることはできません。 – DeiDei

+2

@DeiDei:設計がそのままであるという事実は、委員会メンバーがあなたの見解に同意していないことを示しています。はい、それは権威の議論です。私は、そのような権威の議論が、現実の故意の無知に対して効果的な唯一のものであることを見出しました。 –

+2

@DeiDei:コンテナサイズに署名付きの型を使用することについては説得力がありますが(IMHO説得力はありますが)、Lakosは大規模なC++の本では、興味がありますが、最善の方法は 'abs(c1.size() - c2.size())'の単純で直観的な使用をサポートすることです。さらに、型指定されていないマクロのようなものは、サイズを提供するために使用され、大きすぎる場合を除き、デフォルトでは 'int'になります。そのような型が 'copy_n'に無意識に渡されるなら、*未定義の振る舞い*を持つことは全く必要でなく、非常に危険な考えです。 –

3

総称のためです。
コンテナsize_type(C++)は通常size_tです。しかし、カスタムコンテナを使用したり、カスタムアロケータを使用したりすると、テンプレートパラメータとなることはありません。 custom containerについては

size_typeは(それがan unsigned integer large enough to represent all positive values of difference_typeなければならない)size_tへのtypedefである必要はありません。

STLコンテナの場合、size_typeは、default allocatorの場合はsize_tであるallocator::size_typeのtypedefです。しかし、カスタム・アロケータを指定すると、タイプが異なる可能性があります。

+0

iterator_traits :: difference_typeにすることができます。そして、 'distance(result、return_value)== count'と指定します。しかし、入力専用と出力専用のイテレータではあいまいな意味があります。 –

+0

@ ConstantinBaranov:C++ 11では、 "非負整数i

+0

ああ、C++ 11§25.1/ 12で定義されています。今日も何かを学んだ。まだ死んでいない、hallelujah!ああ、ダン、私は無神論者です。まあ、とにかく。 –

関連する問題