From: A on
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
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
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
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
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! ]