9

この質問は、静的に既知のサイズの配列を受け取る関数に関するものです。

たとえば、次の最小限のプログラムを考えてみましょう。

#include <iostream>

template<size_t N>
void arrfun_a(int a[N])
{
    for(size_t i = 0; i < N; ++i)
        std::cout << a[i]++ << " ";
}

int main()
{
    int a[] = { 1, 2, 3, 4, 5 };
    arrfun_a<5>(a);
    std::cout << std::endl;
    arrfun_a<5>(a);

    return 0;
}

これを実行すると、期待される結果が出力されます。

2 3 4 5 6
3 4 5 6 7

ただし、コンパイラ(VS 2010)にを推測させようとすると5、それが発生しcould not deduce template argument for 'int [n]' from 'int [5]'ます。

少し調べた結果arrfun_b、テンプレートパラメータの推定が機能する場所が更新されました。

template<size_t n>
void arrfun_b(int (&a)[n])
{
    for(size_t i = 0; i < n; ++i)
        std::cout << ++(a[i]) << std::endl;
}

プログラムの結果は、呼び出されても呼び出されても同じarrfun_aですarrfun_b

これまでのところ、私が見つけた唯一の違いは、テンプレート引数の推論が機能するかどうか、および5ではないNで関数を呼び出すことが可能かどうかです...

4

2 に答える 2

15

コンパイラは、関数の引数の型をサイレントに変更するint a[N]ためint *a、配列のサイズが失われます。int(&a)[5]は実際にはサイズ5の配列への参照であり、他のサイズの配列を渡すことはできません。

于 2012-05-08T19:37:17.133 に答える
1

参照とポインタの違いだと思います。

arrfun_a は int へのポインタを渡します。

arrfun_b は、int の配列への参照を渡します。

于 2012-05-08T19:39:49.277 に答える