0

次のように配列を初期化する方法はありますか:

static const vec3d<long> XI[Q] = {
     vec3d<long>( 0, 0, 0 ),

 vec3d<long>(-1, 0, 0 ),  vec3d<long>( 0,-1, 0 ),  vec3d<long>( 0, 0,-1 ),
 vec3d<long>(-1,-1, 0 ),  vec3d<long>(-1, 1, 0 ),  vec3d<long>(-1, 0,-1 ), [etc]
};

どこ

00039 template<typename TYPE>
00040 class vec3d : public vec<TYPE>{
00041 public:
00042 
00049         vec3d() : vec<TYPE>( 0, 3 ){};
00057         vec3d( TYPE right ) : vec<TYPE>( right, 3 ){};
00065         vec3d( TYPE X_val, TYPE Y_val, TYPE Z_val ) : vec<TYPE>( 0, 3 ){
00066                 this->val[0] = X_val;
00067                 this->val[1] = Y_val;
00068                 this->val[2] = Z_val;
00069         };
00077         vec3d( vec3d<TYPE>& right ) : vec<TYPE>( 0, 3 ){
00078                 this->val[0] = right[0];
00079                 this->val[1] = right[1];
00080                 this->val[2] = right[2];
00081         }; [etc] };

    00040 template<typename TYPE>
    00041 class vec{
    00042 public:
    00047         TYPE *val;
    00052         int dimension;
    00053 public:
    00060         vec();
    00066         vec( TYPE right );
    00073         vec( TYPE right, int _dimension );
    00081         vec( vec<TYPE> &right ); 
    00082 
    00087         ~vec();
    00088 
    00089 
    00090         TYPE& operator[]( int right);
    00091         vec<TYPE>& operator=( TYPE right );
    00092         vec<TYPE>& operator=( vec<TYPE> &right );
[etc] };

ソースは次のとおりです。

00049 template<typename TYPE>
00050 vec<TYPE>::vec( TYPE right, int _dimension ){
00051         dimension = _dimension;
00052         val = new TYPE[_dimension];
00053         assert( val );
00054         for( int i = 0; i < dimension; i++ ) val[i] = right;
00055 
00056 };

00075 template<typename TYPE>
00076 TYPE& vec<TYPE>::operator[]( int right ){
00077         assert( ( right < dimension ) );
00078         assert( right >= 0 );
00079         assert( val );
00080         return val[right];
00081 };

コンストラクタです。Q は「static const int」と宣言されているため、非変数であるという C++ 標準を満たす必要がありますね。

コンパイラのメッセージ: エラー: 'albm::vec3d::vec3d(albm::vec3d)' vec3d.h:77:2 への呼び出しに一致する関数がありません: 注: 候補は: albm::vec3d::vec3d(albm:: vec3d&) [TYPE = long int の場合]

明らかに、ここで vec3d& を渡すことができないという問題があります。回避策はありますか?最初にすべてのベクトルを定義することが解決策のようです。ハズレだろうけど…

そして、私の愚かな質問で申し訳ありません...おそらくこのスレッドはどこかに存在しますが、私はそれを見つけられませんでした. おそらく、この問題には私が知らない特別な名前が付いているので、Google で検索することはできません。「拡張初期化子リスト」、「クラス配列の初期化」などはうまくいきませんでした...

解決策:ここでいくつかの後処理...多分そうです。それ以外の場合、同じ問題が発生します: コピー コンストラクターに "const" がありませんでした:

00077         vec3d( const vec3d<TYPE>& right ) : vec<TYPE>( 0, 3 ){
00078                 this->val[0] = right.val[0];
00079                 this->val[1] = right.val[1];
00080                 this->val[2] = right.val[2];

さらに、 right[] に直接アクセスすることはできません-理由はテンプレートスタイルだと思います-しかし、 right.val[] はうまくいきます!

4

2 に答える 2

1

与えられた

00039 template<typename TYPE>
00040 class vec3d : public vec<TYPE>{
00041 public:
00042 
00049         vec3d() : vec<TYPE>( 0, 3 ){};
00057         vec3d( TYPE right ) : vec<TYPE>( right, 3 ){};
00065         vec3d( TYPE X_val, TYPE Y_val, TYPE Z_val ) : vec<TYPE>( 0, 3 ){
00066                 this->val[0] = X_val;
00067                 this->val[1] = Y_val;
00068                 this->val[2] = Z_val;
00069         };
00077         vec3d( vec3d<TYPE>& right ) : vec<TYPE>( 0, 3 ){
00078                 this->val[0] = right[0];
00079                 this->val[1] = right[1];
00080                 this->val[2] = right[2];
00081         }; [etc] };

77行目で定義されているコピーコンストラクターにはconst引数がないため、右辺値引数にバインドできません。

77行目から81行目を削除するだけです。

コンパイラーはあなたのために素晴らしいコピーコンストラクターを生成します。

乾杯&hth。、

于 2011-09-05T07:28:00.017 に答える
0

コピーコンストラクターが正しく宣言されていません-toCopyFromパラメーターはconstである必要があります:

vec3d<TYPE>( const vec3d<TYPE>& toCopyFrom)

編集:

次に、添え字演算子に関する2番目の問題について:

基本クラスの添え字演算子には、 (つまり、読み取り専用の)セマンティクスoperator[]()がありません。constコピーコンストラクターでは、rightその添え字演算子を使用しての値にアクセスしようとしていました。これで、そのrightパラメーターはconstとして宣言されます。これは、基本的に、の内部状態を変更できないことを意味しますrightoperator[]()関数はconstではないため、言語の前提は、関数が-の状態を変更/変更する可能性があるということです。これは、のconst-nessrightと競合します。right実際、この関数は実際にはクラスの内部メンバー変数への参照を返します。これにより、そのコードのクライアントはright!の内部状態を変更できます。

解決策は、基本クラスに追加のconst、添え字演算子を提供することです。

const TYPE& operator[]( int right) const

注-個人的には、わかりやすくするために名前rightを-に変更します。index

上記の関数シグネチャの末尾constは、constアクセスセマンティクスを提供します。これにより、-たとえば--x =whenisを呼び出すことがright[n]できrightますconst。戻り型の先頭のconstは、返されるTYPE参照がconstになることを意味します。これにより、がconstのright[n] = x場合に実行できなくなりますright。注-関数を追加する場合、関数の実装(本体)は、既存の添え字演算子の場合と同じように見えるはずです。あなたはそれを提供しなかったので、私はそれを書くことができません。

結論として、constと「const-correctness」のトピックを読んでおくことをお勧めします。

于 2011-09-05T07:27:39.757 に答える