2011-11-03 19 views
1

サイズ変更可能な配列を使用できるテンプレートを作成しようとしています。 sizeof(T)を見つける方法はありますか?私は、配列のサイズを変更する関数でreallocを使いたいので、新しいものではなくmallocを使用しています。これは、エラーを取得している私のクラスのコンストラクタです:C++でテンプレートを作成するときにsizeof(T)を見つけることは可能ですか?

template <class T> 
set<T>::set(void) { 
arr = malloc(10 * sizeof(T)); 
numElts = 0; 
size = 10; 
}; 

構築しようとしたとき、私は、次のエラーメッセージが表示されます。

私はそれを呼んでいる主な機能には
error C2440: '=' : cannot convert from 'void *' to 'int *' 
1>   Conversion from 'void*' to pointer to non-'void' requires an explicit cast 
1>   c:\set.cpp(42) : while compiling class template member function 'set<T>::set(void)' 
1>   with 
1>   [ 
1>    T=int 
1>   ] 

set<int> *set1 = new set<int>(); 

私が行った研究から、コンパイラはsizeof(T)に何を使うべきかを知る方法がないように見えるので、コンパイルできません。私はこれについて他にどのように行くだろうか?

+4

'set'はPODタイプでのみ動作することに注意してください。 –

+5

エラー*はっきりと述べています。「void *からint *に変換できません。明示的にキャストする必要があることを示唆しています。明らかに、問題は 'sizeof(T)'が何であるかを知らないということです。 –

+0

*コンパイラがsizeof(T)に何を使うべきかを知る方法がないように見える* - もちろんそうです;テンプレートの実装はすべてコンパイル時に実行されます。エラーメッセージはクリアです。 mallocの結果をキャストする必要があります。なぜあなたはmallocをまったく使っているのですか...考えていません。 mallocはコンストラクタをあなたのために呼び出さないでしょう。 –

答えて

13

mallocvoid*を返し、C許さ互換性のないポインタが割り当てられる一方で、C++にはありません。 T*にキャストする必要があります。arrと仮定したmallocの結果はT*と定義されています。

arr = static_cast< T* >(malloc(10 * sizeof(T))); 

限りTがインスタンス化の時点で完了している(とintは基本的なタイプ、その常に完全である)として、テンプレート内sizeof(T)を呼び出すことに問題はありません。

+2

作業コード: 'arr = static_cast (malloc(10 * sizeof(T)));' – Pubby

+0

ありがとう!これは世話をした。 CとC++の違いについて説明してくれてありがとう。 – Dom12

+0

'malloc'を慣用的な方法で使用すると、実際にはキャストは必要ありません。結果のvoidポインタを配置式の引数として使用するためです。キャストは、そのタイプのPODnessを推定するプログラマーの一部の醜いショートカットの症状です。 –

1

あなたは問題を過剰分析していると思います。 mallocによって返されたvoid*T*タイプのarrにキャストする必要があることを伝えるだけです。

1

もちろん可能です。それはあなたが持っているエラーの理由ではありません。

私はset::arrメンバーがT*であると推測しています。 setクラスをテンプレートパラメータタイプintでインスタンス化したので、そのメンバ変数の宣言はint *arr;になります。 C Cと異なり、void *から別のポインタ型に暗黙的にキャストすることはできません。したがって、mallocコールの結果をキャストする必要があります。

arr = static_cast<T *>(malloc(10 * sizeof(T))); 

また、あなたが実際にセットに要素を挿入しているとき、あなたが割り当てられてきたバッファに要素を構築するために配置新しいを使用する必要が、その後、明示的にデストラクタを呼び出すことを覚えているとき、コピー/それらを移動/除去する。

+1

おそらく、空の 'set'が10個の要素を持つのではなく、10個の要素に対して* space *を持つことが意図されています。もちろん、問題を考えると、その可能性はごくわずかです。 –

+1

また、 'realloc' _can_は既存のメモリ(時には)を拡張し、自動的にデータをコピーします。したがってreallocには利点があります。特にPODを扱う場合。 –

+0

@DennisZickefooseはい、そうです。私は 'numElts = 0;'を 'numElts = 10;'と読みます。私は答えを更新しました。 – Praetorian

関連する問題