2013-05-12 12 views
7

私はC++テンプレートの概念を学んでいます。私は以下を理解していません。リファレンスを使用して関数テンプレートに配列を渡す方法

#include <iostream> 
#include <typeinfo> 

using namespace std; 

template <typename T> 
T fun(T& x) 
{ 
cout <<" X is "<<x; 
cout <<"Type id is "<<typeid(x).name()<<endl; 
} 


int main (int argc, char ** argv) 
{ 
    int a[100]; 
    fun (a); 
} 

私は何を試みていますか?

1)Tの楽しみ(T & x)は

ここで、xが参照され、したがって、「」へのポインタ型を減衰し が、コンパイル時ではないだろう、私は次のエラーを取得しています。

error: no matching function for call to ‘fun(int [100])’ 

私が非参照を試みると、正常に動作します。私が理解しているように、配列はポインタ型に崩壊しています。

答えて

16

Cスタイルの配列は、組み込み関数やユーザー定義型のように代入、コピー、参照できない非常に基本的な構造です。すべての配列サイズはT[M]以来、ここでは、配列のサイズは機能が動作できるようにするためにも、テンプレートパラメータであることだろう

// non-const version 
template <typename T, size_t N> 
void fun(T (&x)[N]) { ... } 

// const version 
template <typename T, size_t N> 
void fun(const T (&x)[N]) { ... } 

注:参照によって配列を渡すのと同等を実現するには、次の構文を必要とするために、 T[N]は異なるM,Nの同じタイプではありません。また、この関数はvoidを返します。すでに述べたように、配列はコピー可能ではないので、配列を値で返す方法はありません。

4

戻り値の型に問題があります。配列はコピー不可能なため、配列を返すことはできません。そして、ところで、あなたは何も返さない!

ではなく、試してみてください。

template <typename T> 
void fun(T& x) // <--- note the void 
{ 
    cout <<" X is "<<x; 
    cout <<"Type id is "<<typeid(x).name()<<endl; 
} 

そして期待どおりに動作します。

注:(GCC 4.8での)元のフルエラーメッセージは、実際にある:

test.cpp: In function ‘int main(int, char**)’: 
test.cpp:17:10: error: no matching function for call to ‘fun(int [100])’ 
    fun (a); 
    ^
test.cpp:17:10: note: candidate is: 
test.cpp:7:3: note: template<class T> T fun(T&) 
T fun(T& x) 
^
test.cpp:7:3: note: template argument deduction/substitution failed: 
test.cpp: In substitution of ‘template<class T> T fun(T&) [with T = int [100]]’: 
test.cpp:17:10: required from here 
test.cpp:7:3: error: function returning an array 

最も関連性の高いラインが最後のものです。

+0

"effective modern C++"の項目1もこのように示唆しています。 '(&param)[N]'を書くことは、 'f'の本体で' N'を参照する必要がない限り、冗長です(これは型を取っても推測することができます) –

関連する問題