开发者

Initializing class object-array

Is there a way to initialize an array like so:

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]
};

where

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] };

and

    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] };

Source is:

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 };

are constructors. Q is declared "static const in开发者_StackOverflow社区t", so it should fulfil C++ standard of being non-variable, right?

Compiler says: error: no matching function for call to ‘albm::vec3d::vec3d(albm::vec3d)’ vec3d.h:77:2: note: candidates are: albm::vec3d::vec3d(albm::vec3d&) [with TYPE = long int]

Obviously there is the problem, that I can't pass vec3d& here. Is there some workaround? Defining every single vector first seems to be a solution. Would be a hazzle though...

And sorry for my stupid question...maybe this thread exists somewhere, but I didn't find it. Probably this issue has some special name I don't know - therefore I can't google it! "extended initializer list", "class array initialisation" and such didn't do the trick...

SOLUTION: some postprocessing here...maybe so. else encounters the same prob: The copy constructor lacked a "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];

Further I can't access right[] directly - my guess for a reason would be the template-style - but right.val[] does the trick!


Given

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] };

the copy constructor defined at line 77 has non-const argument, which cannot be bound to an rvalue argument.

Just remove lines 77 through 81.

The compiler will generate a nice copy constructor for you.

Cheers & hth.,


Your copy-constructor is not correctly declared - the toCopyFrom parameter needs to be const:

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

Edit:

Now, on your second problem regarding the subscript operator:

The subscript operator operator[]() in your base class does not have const (i.e. read-only) semantics. In your copy constructor, you were trying to access values in right through that subscript operator. Now, that right parameter is declared const, which basically means that you are not allowed to change the internal state of right. Since your operator[]() function is not const, the language's assumption is that the function could mutate/alter the state of right - which conflicts with right's const-ness. Indeed, the function actually returns a reference to the internal member variables of the class, which would allow a client of that code to change the internal state of right!

The solution is to provide an additional, const, subscript operator in the base class:

const TYPE& operator[]( int right) const

Note - personally, I'd rename right to index - for clarity.

The trailing const on the above function signature provides it with const access semantics, which allows you to call - for instance - x = right[n] when right is const. The leading const on the return type just means that the returned TYPE reference will be const, which prevents you doing right[n] = x when right is const. Note - when you add the function, its implementation (body) of the function should probably look the same as for the existing subscript operator. You did not provide that, so I cannot write it.

In conclusion, I would suggest you read up on const and 'const-correctness' topics.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜