web-dev-qa-db-ja.com

C ++は配列を参照渡しします

これは参照によって配列を渡すことができますか?

 void foo(double& *bar) 

私のコンパイラはノーと言っているようです。どうして?配列を参照渡しする適切な方法は何ですか?または回避策ですか?メソッドに変更を加え、後で取得する配列引数があります。あるいは、この配列をクラスメンバにすることもできますが、これは正常に動作しますが、コードの他の部分には多くの欠点があります(回避したい)。

よろしくお願いします。

60
kiriloff

配列は、実際には参照によってのみ渡すことができます。

void foo(double (&bar)[10])
{
}

これにより、次のようなことができなくなります。

double arr[20];
foo(arr); // won't compile

任意のサイズの配列をfooに渡すことができるようにするには、それをテンプレートにして、コンパイル時に配列のサイズをキャプチャします。

template<typename T, size_t N>
void foo(T (&bar)[N])
{
    // use N here
}

std::vectorの使用を真剣に検討する必要があります。または、c ++ 11をサポートするコンパイラがある場合は、std::arrayを検討する必要があります。

96
jrok

はい。ただし、参照の引数の一致時に、ポインタへの暗黙的な配列は自動ではないため、次のようなものが必要です。

void foo( double (&array)[42] );

または

void foo( double (&array)[] );

ただし、一致する場合、double [42]double []は別個のタイプであることに注意してください。不明な次元の配列がある場合、2番目の要素と一致しますが、最初の要素とは一致しません。42個の要素を持つ配列がある場合、最初の要素と一致します2番目ではありません。 (後者は、私見では、非常に直感に反します。)

2番目のケースでは、関数内に入るとディメンションを回復する方法がないため、ディメンションも渡す必要があります。

13
James Kanze

C++を使用しているので、ここでまだ欠けている義務的な提案は、std::vector<double>を使用することです。

参照で簡単に渡すことができます:

void foo(std::vector<double>& bar) {}

また、C++ 11をサポートしている場合は、std::arrayもご覧ください。

参考のため:

6
moooeeeep

要素のみを変更する場合:

void foo(double *bar);

十分です.

アドレスを(たとえば:realloc)に変更したいが、配列では機能しない場合:

void foo(double *&bar);

正しい形式です。

6
Naszta

8.3.5.8パラメータの型に「Tの未知の境界の配列へのポインタ」または「Tの未知の境界の配列への参照」という形式の型が含まれている場合、プログラムの形式は正しくありません。

3
Kirilodius

他の答えが言うように、&の後に*を置きます。

これにより、混乱を招く可能性のある興味深い点が生じます。型は右から左に読む必要があります。たとえば、これは(右端の*から始まる)intへの定数ポインターへのポインターです。

int * const *x;

したがって、あなたが書いたのは参照へのポインタになりますが、これは不可能です。

2
parkovski