runtime error

aortizb's Avatar, Join Date: Sep 2008
Go4Expert Member
Can somebody tell me why this code does not work and how to fix it? It compiles but runtime errors appear:

Code:
#include <iostream>
#include <vector>
using namespace std;  

template <class T>
class Vec
{
public:
  // constructors
  Vec(int length); 
  Vec(int length, T typeValue); 
  Vec(const Vec<T>& rhsObj); 
  const Vec<T>& operator=(const Vec<T>& rhsObj);
  const Vec<T>& operator=(T& typeValue);
  const Vec<T>& operator*=(T typeVal);
  const Vec<T> operator*(T typeVal) const;
  const T& operator()(int index) const;
  T& operator()(int index);
  int getSize() const;
  ~Vec();
private:
  vector<T> myVec_;
};


template<class T> 
Vec<T>::
Vec(int length)
{
  myVec_ = vector<T>(length);
}

template<class T> 
Vec<T>::
Vec(int length, T typeValue)
{
  myVec_ = vector<T>(length,typeValue);
}

template<class T> 
Vec<T>::
Vec(const Vec<T>& rhsObj) 
{
  vector<T> myVec_(rhsObj.myVec_);
}

template<class T> 
const Vec<T>& 
Vec<T>::
operator=(const Vec<T>& rhsObj)
{
  myVec_ = rhsObj.myVec_;
  return *this;
}

template<class T> 
const Vec<T>& 
Vec<T>::
operator=(T& typeValue)
{
  for (unsigned i = 0; i < myVec_.size(); i++)
    (*this)(i) = typeValue;
  return *this;
}

template<class T>
const Vec<T>&
Vec<T>::
operator*=(T typeVal)
{  
  for (unsigned i = 0; i < myVec_.size(); i++)
  {
    (*this)(i) *= typeVal; 
  }
  return *this;
} 

template<class T>
const Vec<T>
Vec<T>::
operator*(T typeVal) const
{
  return (Vec<T>(*this) *= typeVal);
} 

template<class T>
const T&
Vec<T>::
operator()(int index) const
{
  return myVec_[index];
} 

template<class T>
T&
Vec<T>::
operator()(int index)
{
  return myVec_[index];
} 

template<class T> 
int
Vec<T>::
getSize() const
{
  return (myVec_.size());
}

template<class T> 
Vec<T>::
~Vec()
{
}


// ******************************************************************************
// overloading externally since the first argument is not an object: typeVal*obj1
// ******************************************************************************
template<class T>
const Vec<T>
operator*(const T typeVal, const Vec<T>& obj1)
{
  return (obj1*typeVal);
}


int main()
{
  Vec<double> x(3,4);
  Vec<double> d = x*2.0;
  cout << d(0) << " " << d(1) << " " << d(2) << endl;
  return 0;
}
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
What's it meant to do?
What output do you expect from this code? (In particular, why do you expect THREE values, and what are they?)
What are the errors?
0
aortizb's Avatar, Join Date: Sep 2008
Go4Expert Member
the code above is just a portion of another code that does some operations with vectors. At the beggining I created it as a child of std::vector, but i read that this is not a good idea, so i decided to do a wrapper of std::vector. The ouput to identify the error is just what i have in main(). The error is becuase "d" is not being compute, so d(0), d(1) and d(2). The problem is fixed when i remove the copy constructor, so the problem is there. I don't see why it is wrong? can anyone tell me how to rewrite the copy constructor? in principle, i don't need it since the default created by the compiler will be ok. But for generality i would like to know how to do it.

thanks.
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
Are you sure the copy constructor is being invoked? For example have you tried putting a printf or a cout into it?
TYPE var=<expr>; can sometimes invoke the copy constructor or operator=(), hence the question.
0
aortizb's Avatar, Join Date: Sep 2008
Go4Expert Member
Yes, I tried. It is being invoked.
0
aortizb's Avatar, Join Date: Sep 2008
Go4Expert Member
The correct constructor is:
Code:
template<class T> 
Vec<T>::
Vec(const Vec<T>& rhsObj) 
{
  myVec_ = rhsObj.myVec_;
}
or
Code:
template<class T> 
Vec<T>::
Vec(const Vec<T>& rhsObj) :  myVec_ (rhsObj.myVec_)
{
}
with this the code above is fixed.
Also, is there any way I can do the following in the main() function:
Code:
 int main()
{
  Vec<double> x(3,4);
  Vec<double> d = 2*x;
  cout << d(0) << " " << d(1) << " " << d(2) << endl;
  return 0;
}
without incurring in a compilation error because of 2 can be interpreted as more than one type? I mean I would like this to compile independently if I use 2*x or 2.0*x
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
I still don't see what numbers you're expecting this to output. I can guess that d(0) will be 6 and d(1) will be 8, but what do you think d(2) will be?
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
For 2*x to work you need operator*(int,Vec).
0
aortizb's Avatar, Join Date: Sep 2008
Go4Expert Member
No, d(0)=d(1)=d(2) = 8. There is an easy way to solve all posibilities no matter if it is integer or double. I found it today in the morning:

Code:
template<class T, class U>
const Vec<T>
operator*(const U typeVal, const Vec<T>& obj1)
{
  return (obj1*typeVal);
}