参照による配列の受け渡し


184

静的に割り当てられた配列を参照渡しする方法は?

void foo(int (&myArray)[100])
{
}

int main()
{
    int a[100];
    foo(a);
}

(&myArray)[100]参照することにより任意の配列を渡すために何の意味やそのわずかな構文がありますか?ここでは、括弧とそれに続く大括弧が別々に理解できません。ありがとう。


関数パラメーターとのRvalueとLvalueの関係はありますか?
John DB


回答:


228

これは、配列参照の構文です- (&array)(無効な)参照の配列ではなく、配列への参照が必要であることをコンパイラに明確にするために使用する必要がありますint & array[100];

編集:いくつかの明確化。

void foo(int * x);
void foo(int x[100]);
void foo(int x[]);

これら3つは、同じ関数を宣言する異なる方法です。それらはすべてint *パラメータを取るものとして扱われ、任意のサイズの配列を渡すことができます。

void foo(int (&x)[100]);

これは100個の整数の配列のみを受け入れます。あなたは安全に使用することができますsizeofx

void foo(int & x[100]); // error

これは「参照の配列」として解析されます-これは合法ではありません。


参照の配列ができないのはなぜint a, b, c; int arr[3] = {a, b, c};ですか?
Vorac

4
ああ、その理由がわかりました。
Vorac

2
誰かvoid foo(int & x[100]);が「参照の配列」として解析される理由を誰かが説明できますか?「右から左へ」というルールが原因ですか?はいの場合、void foo(int (&x)[100]);「配列への参照」として解析される方法と一致しないようです。前もって感謝します。
zl9394 2017

3
それは右から左ではなく、裏返しであり、[]は&よりも強く結合します。
philipxy

48

これは必要な構文です。

void Func(int (&myArray)[100])

^ intパラメータ名がである参照により100の配列を渡しますmyArray

void Func(int* myArray)

^配列を渡します。配列はポインタに減衰します。したがって、サイズ情報が失われます。

void Func(int (*myFunc)(double))

^関数ポインタを渡します。関数はを返し、intを受け取りますdouble。パラメータ名はmyFuncです。


可変サイズの配列を参照として渡すにはどうすればよいですか?
Shivam Arora 2017年

@ShivamArora関数をテンプレート化し、サイズをテンプレートパラメータにします。
マーティンヨーク

24

構文です。関数の引数ではint (&myArray)[100]、を囲む括弧&myArrayが必要です。それらを使用しない場合は、が渡されます。array of referencesこれは、subscript operator []がに優先されるためです。& operator。です。

例えば int &myArray[100] // array of references

したがって、を使用しtype construction ()て、100の整数の配列への参照が必要であることをコンパイラに伝えます。

例えば int (&myArray)[100] // reference of an array of 100 ints


「それらを使用しない場合、渡されますarray of references」-もちろん、これは存在できないため、コンパイルエラーが発生します。とにかく、これはデフォルトで発生するはずであると演算子の優先順位ルールが主張しているのは面白いです。
underscore_d

型構築()に関するチュートリアルは他にありますか?
チーフシフター

おかげで、演算子の優先順位に関する理由が含まれている説明が必要でした。これにより、なぜこのようにする必要があるのか​​がわかります。
cram2208 2017年

4

配列はデフォルトでポインタによって渡されます。理解を深めるために、関数呼び出し内で配列を変更してみてください。


2
配列を値で渡すことはできません。関数がポインターを受け取ると、配列はその最初の要素へのポインターに減衰します。ここで何を言おうとしているのかわかりません。
Ulrich Eckhardt 2015

@UlrichEckhardt前に言ったように、「配列は値で渡すことはできません」と言いたいのですが、デフォルトで参照渡しされます
Eduardo A.FernándezDíaz15年

8
配列は値でも参照でも渡されません。それらはポインタによって渡されます。配列がデフォルトで参照渡しされる場合、配列でsizeofを使用しても問題はありません。しかし、そうではありません。配列は、関数に渡されるとポインタに崩壊します。
user3437460 2016年

2
配列は、参照によって渡すことも、ポインターにデグレードすることによって渡すこともできます。たとえば、を使用するとchar arr[1]; foo(char arr[]).、arrはポインタに低下します。の使用中char arr[1]; foo(char (&arr)[1])、arrは参照として渡されます。次元が失われているため、前者のフォームは誤った形式であると見なされることがよくあります。
zl9394 2017

再度、「配列は...ポインタによって渡されます。」その説明は、型破りに聞こえるだけで、初心者にはわかりにくいかもしれません。配列変数の名前は、値が配列の最初のメンバーのポインターである有効な式です。何らかの関数foo(T* t)があり、配列があるT a[N];場合、書くときは、配列foo(a);ではなくポインタを渡し、値によってポインタを渡すと言った方が正しいと思います。
ソロモンスロー

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.