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.
精彩评论