Prev: In C++0x, shall I delete functions instead of making them private?
Next: GET THE SIZE of struct in the PREPROCESSOR
From: A on 4 Mar 2010 03:09 Hi, I am writing a "vector" class. I know about the STL but I prefer to use this as I use this to create a "matrix" class later. I read that using the inbuilt STL to create a matrix is not the best way to do it. At the moment, the class "vec" looks like this. template <class T> class vec { private: int length; T *v; public: vec(); explicit vec(int n); vec(const T &a, int n); vec(const T *a, int n); vec(const vec &cpy); vec & operator=(const vec &equate); vec & operator=(const T &a); inline T & operator[](const int i); inline const T & operator[](const int i) const; inline int size() const; ~vec(); }; Now, I want to overload the operator == in this way. It should accept a value (type T) say "val", and check through all the entries of this vector say "v1" and return another vector of type bool, which has "false" where v1 != val and "true" where v1 == val. I managed to write it this way... member function: vec<bool> operator==(const T &a) const; the code definition is: template <class T> vec<bool> operator==(const T &a) const { vec<bool> tmp(false,length); for(int i=0; i<length; i++) { if(v[i] == a) { tmp[i] = true; } } return tmp; } This works great, but I would like to return the reference instead of the whole vector and would like to know how to do it. I am unable to make use of the "this" pointer as I am returning a "local vector". I would appreciate any help with this. thank you! -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 4 Mar 2010 06:19 On 4 Mrz., 21:09, A <aragorn1...(a)gmail.com> wrote: > I am writing a "vector" class. I know about the STL but I prefer to > use this as I use this to create a "matrix" class later. I read that > using the inbuilt STL to create a matrix is not the best way to do it. This is correct, but have you considered std::valarray? (see below) > At the moment, the class "vec" looks like this. > template <class T> > class vec { > private: > int length; > T *v; > public: > vec(); > explicit vec(int n); > vec(const T &a, int n); > vec(const T *a, int n); > vec(const vec &cpy); > vec & operator=(const vec &equate); > vec & operator=(const T &a); > inline T & operator[](const int i); > inline const T & operator[](const int i) const; > inline int size() const; > ~vec(); > > }; > > Now, I want to overload the operator == in this way. It should accept > a value (type T) say "val", and check through all the entries of this > vector say "v1" and return another vector of type bool, which has > "false" where v1 != val and "true" where v1 == val. I managed to write > it this way... > > member function: > vec<bool> operator==(const T &a) const; > > the code definition is: > template <class T> > vec<bool> operator==(const T &a) const { > vec<bool> tmp(false,length); > for(int i=0; i<length; i++) { > if(v[i] == a) { > tmp[i] = true; > } > } > return tmp; > > } Remark: I suggest to use free function templates instead of member functions. IMO user's would find it rather astonishingly that they can write vec<double> vc = ...; bool test = vc == 1.2; but not bool test = 1.2 == vc; Note also that std::valarray provides the functionality you are describing here: It provides the following free operator== overloads: template<class T> valarray<bool> operator==(const valarray<T>&, const valarray<T>&); template<class T> valarray<bool> operator==(const valarray<T>&, const T&); template<class T> valarray<bool> operator==(const T&, const valarray<T>&); and all the other comparison functions. > This works great, but I would like to return the reference instead of > the whole vector and would like to know how to do it. I am unable to > make use of the "this" pointer as I am returning a "local vector". I > would appreciate any help with this. thank you! No, you cannot do so: The local variable will be destroyed, before it could be reasonably used. You could keep an internal member of type vec<bool> in vec<T>, but I do not recommend that. Why do you want to do that? [Before you mention performance issues: Have you measured that this copy is the bottleneck of the whole operation in your programs?] Greetings from Bremen, Daniel Kr�gler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Martin B. on 4 Mar 2010 17:56 A wrote: > Hi, > I am writing a "vector" class. I know about the STL but I prefer to > use this as I use this to create a "matrix" class later. I read that > using the inbuilt STL to create a matrix is not the best way to do it. > > At the moment, the class "vec" looks like this. > template <class T> > class vec { > (....) > }; > > Now, I want to overload the operator == in this way. It should accept > a value (type T) say "val", and check through all the entries of this > vector say "v1" and return another vector of type bool, which has > "false" where v1 != val and "true" where v1 == val. I managed to write > it this way... > (....) Don't! The idea of such a feature is very nice, but do not use operator== for this. Add a function vec<bool> vec::equality_vec(vec const&) or whatever, but let operator== return a simple bool value or else the users of the code will be very confused. br, Martin -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Ulrich Eckhardt on 4 Mar 2010 17:58 A wrote: > I am writing a "vector" class. I know about the STL but I prefer to > use this as I use this to create a "matrix" class later. I read that > using the inbuilt STL to create a matrix is not the best way to do it. Ahem, no? I mean such a general statement is not generally true. How and if you can use std::vector depends on how your matrix class eventually looks like. What I can say is that generally the standard-supplied classes are of better quality than those you roll yourself. > template <class T> > class vec { > private: > int length; > T *v; > public: > vec(); > explicit vec(int n); > vec(const T &a, int n); > vec(const T *a, int n); > vec(const vec &cpy); > vec & operator=(const vec &equate); > vec & operator=(const T &a); > inline T & operator[](const int i); > inline const T & operator[](const int i) const; > inline int size() const; > ~vec(); > }; First thing I see which strikes me as wrong is the use of 'int' for the length, as opposed to size_t. Further, there are no iterators, no reserve memberfunction or generally functions to change the size or insert/delete elements. Using this is IMHO not a better replacement for std::vector. > Now, I want to overload the operator == [...] > > member function: > vec<bool> operator==(const T &a) const; [...] > This works great, but I would like to return the reference instead of > the whole vector and would like to know how to do it. I am unable to > make use of the "this" pointer as I am returning a "local vector". Why do you want that? If you think about speed, profile that first and then apply MOJO[1] if necessary. Otherwise, you can't. What you could do is to pass in a reference to the output vector, but then you can't use operator==, that only works in a function. > if(v[i] == a) { > tmp[i] = true; > } This boils down to if(/boolean expression/ == true) tmp[i] = true; The else branch is not present, but you have the initialisation of 'tmp' with 'false' earlier on. Safe yourself that trouble and simply do: tmp[i] = v[i]==a; Uli [1] Search the web for "C++ MOJO". -- Sator Laser GmbH Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932 [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel T. on 4 Mar 2010 17:54
A <aragorn168b(a)gmail.com> wrote: > I am writing a "vector" class. I know about the STL but I prefer to > use this as I use this to create a "matrix" class later. I read that > using the inbuilt STL to create a matrix is not the best way to do it. Nonsense. Using a vector of vectors to create a matrix is a bad idea, but then so is using a vec of vecs. Using a singe vector to represent a Matrix is a fine idea. template < typename T, typename rep_type = typename std::vector< T > > class Matrix { public: typedef typename rep_type::size_type size_type; typedef typename rep_type::reference reference; typedef typename rep_type::const_reference const_reference; Matrix( size_type w, size_type h ): _width( w ), _height( h ), _rep( w * h ) { } size_type width() const { return _width; } size_type height() const { return _height; } reference at( size_type x, size_type y ) { if ( x >= _width || y >= _height ) throw std::out_of_range( "Matrix::at(size_type, size_type)" ); return _rep[ x * _width + y ]; } const_reference at( size_type x, size_type y ) const { if ( x >= _width || y >= _height ) throw std::out_of_range ( "Matrix::at(size_type, size_type) const" ); return _rep[ x * _width + y ]; } void swap( Matrix& m ) { std::swap( _width, m._width ); std::swap( _height, m._height ); _rep.swap( m._rep ); } private: typename rep_type::size_type _width, _height; rep_type _rep; }; Then you can: Matrix<int> myIntMatrix(4, 4); // a 4 x 4 matrix int value = myIntMatrix.at(2, 2); // access a location myIntMatrix.at(2, 2) = 12; // assign to a location The above should get you started in the right direction. Note that this can use a deque in its guts if you want it to. > At the moment, the class "vec" looks like this. > template <class T> > class vec { > private: > int length; > T *v; > public: > vec(); > explicit vec(int n); > vec(const T &a, int n); > vec(const T *a, int n); > vec(const vec &cpy); > vec & operator=(const vec &equate); > vec & operator=(const T &a); > inline T & operator[](const int i); > inline const T & operator[](const int i) const; > inline int size() const; > ~vec(); > > }; > > Now, I want to overload the operator == in this way. It should accept > a value (type T) say "val", and check through all the entries of this > vector say "v1" and return another vector of type bool, which has > "false" where v1 != val and "true" where v1 == val. I managed to write > it this way... > > member function: > vec<bool> operator==(const T &a) const; > > the code definition is: > template <class T> > vec<bool> operator==(const T &a) const { > vec<bool> tmp(false,length); > for(int i=0; i<length; i++) { > if(v[i] == a) { > tmp[i] = true; > } > } > return tmp; > > } > > This works great, but I would like to return the reference instead of > the whole vector and would like to know how to do it. I am unable to > make use of the "this" pointer as I am returning a "local vector". I > would appreciate any help with this. thank you! What you wrote is cool and all, but it not a good idea. op== have very specific semantics and when you use something odd like this, things get dicey for people trying to use your class and other code that expects op== to work a particular way. Better would be to make a named function that does this job. That said, in order to return a const reference. The vector<bool> has to live longer than the function and that means it would have to be a member-variable of the class or something like that. However, that is problematic because op== might get called multiple times with different values on the right hand side and then what do you do? I suggest you let the function return the vector<bool> and be happy. The compiler will probably optimize out the apparent extra copy. If you profile your product and find that the time spent calling this function is a bottleneck, you might be able to save some time by adding a non-const reference to the parameter list: void vec<T>::values_equal(const T& a, vector<bool>& result); Then load up the 'result' parameter with the proper values. The calling code can hopefully reuse the result parameter and thereby possibly reduce runtime. (Note all the qualifiers.) -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |