次のような関数に引数を渡しているとします。
void myFunc( int* arrayOfInts );
関数がintの配列のサイズを知らないという意味で、これは安全ではないようです。「この関数は10intの配列を取得していることを前提としています」というコメントを付けることはできますが、確認することはできません。したがって、この関数の誤った使用は、不思議な「セグメンテーション違反」につながる可能性があります。これを行うためのより良い方法はありますか?
次のような関数に引数を渡しているとします。
void myFunc( int* arrayOfInts );
関数がintの配列のサイズを知らないという意味で、これは安全ではないようです。「この関数は10intの配列を取得していることを前提としています」というコメントを付けることはできますが、確認することはできません。したがって、この関数の誤った使用は、不思議な「セグメンテーション違反」につながる可能性があります。これを行うためのより良い方法はありますか?
配列のサイズもCスタイルで渡します。
void myFunc(int* arrayOfInts, int arraySize);
または、配列の終わりの後にポインタを渡す、イテレータスタイル:
void myFunc(int* begin, int* end);
または、または同等のものを渡してstd::vector<int>
、問題を完全に回避します。
void myFunc(const std::vector<int>& vec);
CおよびC++では、生の配列を処理する場合、関数では通常、次のように配列のサイズも渡す必要があります。
void foo(int *arr, size_t size_);
std::vector
しかし、C ++では、とにかく使用しませんか?安全です。
テンプレート機能を使用する
template <int N>
void fmyFunc(int (& array)[N])
{
}
またはSTLコンテナ(最新のC ++コードではより良い方法です)
void fmyFunc(const std::vector<int>& v)
{
}
古い方法は、配列サイズを渡すことです
void fmyFunc(int* arrayOfInts, int size)
{
}
代わりに配列を参照して引数を取り、配列のサイズをテンプレートパラメータにすることができますN
。
template <int N>
void myFunc(int (&arrayOfInts)[N])
{
// here we know the size is N
}
または、関数が特定のサイズの配列(たとえば、サイズ3の配列である3Dポイント)のみを受け入れる必要がある場合は、テンプレートを使用する代わりにそのサイズを指定します。このように、コンパイラは有効な配列を使用してこの関数を呼び出すことしかできません。
void myFunc(int (&arrayOfExactlyThreeInts)[3])
{
}
簡単なC++の答えは、を使用することstd::vector
です。
従来のC/C ++の答えは、配列サイズも引数として受け入れることです。
C++に固有の3番目の答えがあります。配列サイズに特化した関数テンプレートを使用できます。それはあなたがすべきだという意味ではありません。詳細については、既知のサイズのtypedefed配列に対するc++関数テンプレートの特殊化で受け入れられた回答を参照してください。
サイズを示す2番目のパラメーターを使用することを検討してください。またはstd::vector<int>
、関数内でサイズを照会できるようにするを使用することをお勧めします。
サイズを渡すか、できればを使用してstd::vector<int>
ください。
他の人が言っているように、配列のサイズで引数を追加します。これは、さまざまなサイズの配列に対して1つの関数を記述できるようにするためです。配列のサイズを計算するテンプレート関数を作成するというアプローチは、テンプレートに渡される配列サイズごとに異なる関数があることを意味します。そして、はい、avector
は独自のサイズを持ち歩きますが、それを実行できるようにオーバーヘッドを追加します。最も単純なものが最適な場合もあります。