Hello all, the code below is a vector class which is a child of the STL vector class. The code below will generate an error when doing this in the main function:

Vec<double> d = 2*x,

since 2 can be understood as an integer or double. If I do the following:

Vec<double> d = 2.0*x

will be ok, since 2.0 is a double.

Can anyone tell me how can I fix my code, so that when one does any of the above two lines no error appears and of course the result is correct? That is, i want that this

Vec<double> d = 2*x
or
Vec<double> d = 2.0*x

can be done without errors.

Thanks.

 ``123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107`` ``````#include #include using namespace std; template class Vec : public vector { public: // constructors Vec(); Vec(int length); Vec(int length, T typeValue); Vec(const Vec& rhsObj); const Vec& operator=(const Vec& rhsObj); const Vec& operator=(T& typeValue); const Vec& operator*=(T typeVal); const Vec operator*(T typeVal) const; ~Vec(); }; template Vec:: Vec() : vector() { } template Vec:: Vec(int length) : vector(length) { } template Vec:: Vec(int length, T typeValue) : vector(length,typeValue) { } template Vec:: Vec(const Vec& rhsObj) : vector(rhsObj) { } template const Vec& Vec:: operator=(const Vec& rhsObj) { vector::operator =(rhsObj); return *this; } template const Vec& Vec:: operator=(T& typeValue) { for (int i = 0; i < this->size(); i++) (*this)[i] = typeValue; return *this; } template const Vec& Vec:: operator*=(T typeVal) { for (unsigned i = 0; i < this->size(); i++) (*this)[i] *= typeVal; return *this; } template const Vec Vec:: operator*(T typeVal) const { return (Vec(*this) *= typeVal); } template Vec:: ~Vec() { } // ****************************************************************************** // overloading externally since the first argument is not an object: typeVal*obj1 // ****************************************************************************** template const Vec operator*(const T typeVal, const Vec& obj1) { return (obj1*typeVal); } int main() { Vec x(3,4); Vec d = 2*x; cout << d[0] << " " << d[1] << " " << d[2] << endl; return 0; }``````
Make the length constructor `explicit`.
1. std::vector isn't prepared to be inherited from.
2. Have you tried x*2?
Yes, I also have * overloaded as a member function in my full code (not shown above). In that case I can do x*2 or x*2.0 without problems ... I think because 2 is automatically converted to double. With the approach in the code shown above, I wanted to compute in the inverse order, that is: 2*x, this way I could do it in both ways, x*2 or 2*x.
thanks both.

1) I don't see why should I use `explicit` in the length constructor. can you explian more?

2) My full code has also other functions and i don't have problems with the heritage from std::vector class? can you explian what also could go wrong if i use std::vector as the parent class?

In response to 1):

 ``12345678910111213141516171819202122232425262728293031`` ``````class Thing { private: std::string stuff; public: Thing(); explicit Thing(int); Thing(std::string); } Thing::Thing() : stuff() { } Thing::Thing(int data) { //do stuff with int... } Thing::Thing(std::string data) { //do stuff with string... } int main() { int a = 0; std::string b = "data"; Thing something; //works Thing something2(a); //works //Thing something3 = a; //does not work, the int constructor must be explicitly called like the above Thing something4(b); //works Thing something5 = b; //works, same as something4 return 0; }``````
Helios,

Ok. I see the point. Now, I have changed the code, so now the functions are overloaded as free functions. The code is:

 ``1234567891011121314151617181920212223242526272829303132333435`` ``````#include #include using namespace std; template const vector& operator*=(vector& obj1, const T typeVal) { for (unsigned i = 0; i < obj1.size(); i++) obj1[i] *= typeVal; return obj1; } template const vector operator*(const vector& obj1, const T typeVal) { return (vector(obj1) *= typeVal); } template const vector operator*(const T typeVal, const vector& obj1) { return (obj1*typeVal); } int main() { vector x(3,4); vector d = x*2.0; cout << d[0] << " " << d[1] << " " << d[2] << endl; return 0; }``````

Further questions:

1)Now, my problem is twofold: I have to explicitly use 2.0*x and x*2.0. Is there any way that the code works fine independently if I use 2 or 2.0? Also, one point that it is important to me. This modified code works fine under MVS, but it won't work under GNU compiler. That is, if I use g++ main.cpp, it will produce an error because there is no *= that matches the overloaded operators in std::vector class. How can i make it so that it can also be built in the GNU compiler?

2) How can I overload (), so that I can use it as x(i) rather than x[i]? I tried to do it overlading () as a free function but the compiler complains that () must be a non-static member.

Last edited on
1) Perhaps this does more than you want:
 ``12345678910111213141516171819202122232425262728293031323334353637383940`` ``````#include #include using namespace std; // The original template version is no longer needed, thus removed template const vector& operator*(vector& obj1, const U typeVal) { for (unsigned i = 0; i < obj1.size(); i++) obj1[i] *= typeVal; return obj1; } template const vector& operator*(const U typeVal, vector& obj1) { return (obj1 * typeVal); } int main() { vector x(3,4); vector d = x * 2.0; vector x2(3,4); vector d2 = x2 * 2; vector x3(3,4); vector d3 = 2 * x3; vector x4(3,4); vector d4 = x4 * 2.2; vector x5(3,4); vector d5 = 2.3 * x5; cout << d[0] << " " << d[1] << " " << d[2] << endl; cout << d2[0] << " " << d2[1] << " " << d2[2] << endl; cout << d3[0] << " " << d3[1] << " " << d3[2] << endl; cout << d4[0] << " " << d4[1] << " " << d4[2] << endl; cout << d5[0] << " " << d5[1] << " " << d5[2] << endl; return 0; }``````

It works as long as type U can be implicitly converted to type T (e.g., from int to double).
Last edited on
I see. Thanks. I am thinking in doing a wrapper to the std::vector (i have posted part of the code here: http://www.cplusplus.com/forum/general/13931/ ). What do you think is better? doing the above code or doing the wrapper?

Thanks.
Last edited on
the wrapper is probably a better approach, but also a lot more work (you have to make iterators, etc.)
Topic archived. No new replies allowed.