I have a Class called "Vector". It consists of two private fields: std::vector<double> coordinates and int len. Methoddim() returns len.
I am overloading operator << like that:
friend std::ostream& operator<<(std::ostream& os, Vector& vec )
{
std:: cout << "(";
for ( int i = 0; i < vec.dim(); i++ ) {
if ( i != vec.dim()-1){
os << vec[i] << ", ";
} else {
os << vec[i];
}
}
os << ')';
return os;
}
An operator + like that:
friend Vector operator +(Vector& first, Vector& second)
{
if(first.dim() != second.dim()){
throw std::length_error{"Vectors must be the same size"};
}else {
Vector localVec(first.dim()); // same as {0,0,0...,0} - first.dim() times
for (int i = 0; i < first.dim(); i++){
localVec[i] = first[i] + second[i];
}
return localVec;
}
}
And operator [] like that:
double& operator[](int index)
{
return this->coordinates[index];
}
And here's the problem:
Vector x{1,2,4};
Vector y{1,2,3};
Vector z = x + y;
std:: cout << z; // it works perfectly fine - (2, 4, 7)
std:: cout << x + y; // it gives me an error
could not match 'unique_ptr<type-parameter-0-2, type-parameter-0-3>' against 'Vector'
operator<<(basic_ostream<_CharT, _Traits>& __os, unique_ptr<_Yp, _Dp> const& __p)
It seems to me that this error is related to parameter Vector& vec , but I don't know whether it's right and what should I do to fix it. If anyone could give me a hint (or tell me what I should read more about) - I would be very grateful.
Here's full code:
class Vector
{
private:
std::vector <double> coordinates;
int len;
public:
Vector(): len{0}, coordinates{} {};
Vector(std::initializer_list <double> coordinates_): len{static_cast <int>( coordinates_.size())}, coordinates{coordinates_} {}
Vector(int len) : len{len} {
for(int i = 0; i < len; i++){
coordinates.push_back(0);
}
}
int dim() const
{
return this->len;
}
double& operator[](int index)
{
return this->coordinates[index];
}
friend std::ostream& operator<<(std::ostream& os, Vector& vec )
{
std:: cout << "(";
for ( int i = 0; i < vec.dim(); i++ ) {
if ( i != vec.dim()-1){
os << vec[i] << ", ";
} else {
os << vec[i];
}
}
os << ')';
return os;
}
friend Vector operator +(Vector& first, Vector& second)
{
if(first.dim() != second.dim()){
throw std::length_error{"Vectors must be the same size"};
}else {
Vector localVec(first.dim());
for (int i = 0; i < first.dim(); i++){
localVec[i] = first[i] + second[i];
}
return localVec;
}
}
};
friend std::ostream& operator<<(std::ostream& os, Vector& vec)
This signature doesn't accept rvalues, and this is why the error happens for your temporary result here:
std:: cout << x + y;
Change the second parameter into const Vector& vec or provide an overload with an r-value reference parameter.
friend std::ostream& operator<<(std::ostream& os, const Vector& vec);
A temporary cannot bind to a non-const reference argument. You are missing const in at least two places. Most importantly here:
friend std::ostream& operator<<(std::ostream& os, const Vector& vec )
// ^^
And there should a const overload of operator[]
Related
#include <iostream>
#include <memory>
#include <initializer_list>
#include <cassert>
template <typename T>
class Vector
{
// Your implementation of the Vector class starts here
private:
//attributes
int length;
T* data;
public:
//constructors
Vector()
:length(0),
data(nullptr)
{
std::cout<<"New empty object created"<<std::endl;
}
Vector(int length)
:length(length),
data(new T[length])
{
std::cout<< "Length of object is = " <<length <<std::endl;
}
//use a copy of another Vector
Vector(const Vector& other)
: Vector(other.length)
{
for(int i=0;i<length;i++)
data[i]=other.data[i];
}
// using initializer list
Vector(std::initializer_list<T> list)
: Vector((int)list.size())
{
std::uninitialized_copy(list.begin(), list.end(), data);
std::cout<< "The elements in the object are: ";
for (auto it = std::begin(list); it!=std::end(list); ++it)
std::cout << ' ' << *it;
std::cout<<std::endl;
}
//operators
//copy
Vector<T>& operator=(const Vector<T>& other)
{
if(this!= &other)
{
std::cout<<"Copied constructor"<<std::endl;
delete[] data;
length = other.length;
std::cout<<"New length ="<<length<<std::endl;
data = new T[length];
std::cout<<"The elements in the object are: ";
for(int i=0;i<length;i++)
{
data[i]=other.data[i];
std::cout<<data[i]<<" ";
}
}
std::cout<<std::endl;
//std::cout << "copy operator" << std::endl;
return *this;
}
//move
Vector<T>& operator=(Vector<T>&& other)
{
if(this!= &other)
{
delete[] data;
length = other.length;
data = new T[length];
for(int i=0;i<length;i++){
data[i]=other.data[i];}
other.length = 0;
delete[] other.data;
other.data = nullptr;
}
//std::cout << "Move operator" << std::endl;
return *this;
}
///////////////////////////////////////////////
//add
Vector<T> operator+(const Vector<T>& other) const
{
assert(length == other.length);
Vector<T> newer(length);
std::cout<<"The addition gives: ";
for(auto i=0;i<length;i++)
{
newer.data[i] = data[i]+other.data[i];
std::cout<<newer.data[i]<<" ";
}
std::cout<<std::endl;
return newer;
}
//minus
Vector<T> operator-(const Vector<T>& other) const
{
assert(length == other.length);
Vector<T> newer(length);
for(auto i=0;i<length;i++)
newer.data[i] = data[i]-other.data[i];
return newer;
}
// Multiply by a scalar
Vector<T> operator*(T scalar)
{
Vector<T> newer(length);
std::cout<<"Multiplication of a new vector by scalar provides: ";
for (auto i=0; i<length; i++)
{
newer.data[i] = data[i] * scalar;
std::cout<<newer.data[i]<<" ";
}
std::cout<<std::endl;
return newer;
}
//////////////////////////////////////////
// Add to existing Vector
Vector<T>& operator+=(const Vector<T>& other)
{
for (auto i=0; i<length; i++)
data[i] += other.data[i];
return *this;
}
// Multiply existing Vector by a scalar
Vector<T>& operator*=(T scalar)
{
std::cout<<"Multiplication of an existing vector by scalar provides: ";
for (auto i=0; i<length; i++)
{
data[i] *= scalar;
std::cout<<data[i]<<" ";
}
std::cout<<std::endl;
return *this;
}
double Valueform(int i)
{
return data[i];
}
int Lengthfinder()
{
return length;
}
///////////////////////////////////////////
//destructor
~Vector()
{
delete[] data;
data = nullptr;
length = 0;
}
};
template<typename T>
T dot(const Vector<T>& lhs, const Vector<T>& rhs)
{
// Your implementation of the dot function starts here
T result = 0;
for (auto i=0; i<lhs.Lengthfinder(); i++)
{
result = lhs.Valueform(i)*rhs.Valueform(i);
//result + = multiply(lhs.data[i],rhs.data[i]);
// result += lhs.data[i]*rhs.data[i];
}
return result;
}
//failsafe for value multiplied by a vector
template <typename T, typename I>
Vector<T> operator*(I i,Vector<T> other)
{
std::cout<<"Multiplication was done by a vector and failsafe activated"<<std::endl;
return(other* T(i)) ;
}
int main()
{
Vector<double> a(5);
Vector<double> b({ 1 , 2 , 3 , 4 });
Vector<double> c({ 2 , 3 , 4 });
Vector<double> d({ 5 , 2 , 1 });
// std::cout<< "a=c" <<std::endl;
a = c;
// std::cout<< "e = c+d" <<std::endl;
Vector<double> e;
e = c+d;
// std::cout<< "f = c*5" <<std::endl;
Vector<double> f;
f = c*5;
// std::cout<< "g = 5*d" <<std::endl;
Vector<double> g;
g = 5*d;
Vector<double> Dott;
Dott = dot(c,d);
return 0;
}
The code does not allow me to call for the functions Valueform and Lengthfinder, anyone has a possible work around where I can get specific data values and length since the class variables are private? The functions are mostly worked around the template but I would like to just call 2 functions to get certain attributes and they are giving me errors that shouldn't exist, althought I'm not sure why exactly.
Your dot function is taking constant vectors:
template<typename T>
T dot(const Vector<T>& lhs, const Vector<T>& rhs)
{ // ^^^^^-----------------^^^^^----- these are const
// Your implementation of the dot function starts here
}
But, your member functions are not marked as const. You should declare them const to make these functions available:
double Valueform(int i) const
{
return data[i];
}
int Lengthfinder() const
{
return length;
}
I am trying to understand how to overload the '<<' operator. So i wrote a simple test code that I report part of if here:
class Buffer {
vector<char> buffer;
...
ostream& operator<< (ostream& out, const vector<char>& v) {
out << "[";
size_t last = v.size() - 1;
for(size_t i = 0; i < v.size(); ++i) {
out << v[i];
if (i != last)
out << ", ";
}
out << "]";
return out;
}
...
};
The way I use the class in the main is the usual but I get the following error. Why?
main.cpp:22:10: error: overloaded 'operator<<' must be a binary operator (has 3 parameters)
ostream& operator<< (ostream& out, const vector<char>& v) {
^
It needs to be a binary operator: Since you're adding the operator as a class member, it'll always be called on a instance of that class, like this:
Buffer myBuffer;
const vector<char> myVector;
myBuffer << myVector;
You should see this as a function equivalent to:
myBuffer.DoOperator(myVector);
.. which takes only one argument, not two! So you should skip the first argument!
class Buffer {
vector<char> buffer;
...
friend
ostream& operator<< (ostream& out, const Buffer& b) {
const vector<char>& v=b.buffer;
out << "[";
size_t last = v.size() - 1;
for(size_t i = 0; i < v.size(); ++i) {
out << v[i];
if (i != last)
out << ", ";
}
out << "]";
return out;
}
...
};
I'm having trouble with the syntax for a homework program. The prompt is to overload an inserter in such a way that it can properly execute the program fragment:
for (int i = 0; i < v.size(); ++i)
cout << v[i] << endl;
cout << endl;
So, this is what I have so far, but I still get an error at the cout << v[i] statement (Invalid operands to binary expression):
unsigned int seed;
struct node
{
int integer;
double value;
};
double random(unsigned int &seed);
void initialize_vector(vector<node> &v);
template<typename T>
void print_vector(const vector<T> &v);
template<typename T>
ostream &operator <<(ostream &out, const vector<T> &v);
template<typename T>
void output(ostream &out, const vector<T> &v);
int main()
{
vector<node> v(10);
initialize_vector(v);
print_vector(v);
return 0;
}
double random(unsigned int &seed)
{
const int MODULUS = 15749;
const int MULTIPLIER = 69069;
const int INCREMENT = 1;
seed = ((MULTIPLIER * seed) + INCREMENT) % MODULUS;
return double(seed) / double(MODULUS);
}
void initialize_vector(vector<node> &v)
{
for (int i = 0; i < v.size(); ++i)
{
v[i].integer = int (11 * random(seed));
v[i].value = double (11 * random(seed));
}
}
template<typename T>
void print_vector(const vector<T> &v)
{
for (int i = 0; i < v.size(); ++i)
cout << v[i] << endl;
cout << endl;
}
template<typename T>
ostream &operator <<(ostream &out, const vector<T> &v)
{
output(out, v);
return (out);
}
template<typename T>
void output(ostream &out, const vector<T> &v)
{
cout << v.integer;
cout << setprecision(2) << fixed << setw(6) << v.value;
}
I've tried passing node instead of T, along with passing with and without const references for the last 3 functions, so again I assume my syntax in the void output function is wrong somehow. Any help or points in the right direction would be greatly appreciated.
*Note: I can't change the ostream &operator function.
cout << v[i] << endl;
If v is a vector of node, then you need one more function to overload operator << for a node
ostream &operator <<(ostream &out, const node &n)
{
out << n.interger << " " << n.value;
return out;
}
How could I use operator overloading to add two objects without making it a member of of any object? Is this something to do with insertion operator overloading?
so instead of this, to use something more generic i.e. to be used with any objects?:
sameObjectType operator + ( const sameObjectType &x, const sameObjectType &y ) {
sameObjectType z;
z = x+y;
return z;
}
// I want to do the same for subtraction operatoR
sameObjectType operator - ( const sameObjectType &x, const sameObjectType &y ) {
sameObjectType z;
z = x-y;
return z;
}
You can get the idea from this sample code.
#include <iostream>
class One {
private:
int num1, num2;
public:
One(int num1, int num2) : num1(num1), num2(num2) {}
One& operator += (const One&);
friend bool operator==(const One&, const One&);
friend std::ostream& operator<<(std::ostream&, const One&);
};
std::ostream&
operator<<(std::ostream& os, const One& rhs) {
return os << "(" << rhs.num1 << "#" << rhs.num2 << ")";
}
One& One::operator+=(const One& rhs) {
num1 += rhs.num1;
num2 += rhs.num2;
return *this;
}
One operator+(One lhs, const One &rhs)
{
return lhs+=rhs;
}
int main () {
One x(1,2), z(3,4);
std::cout << x << " + " << z << " => " << (x+z) << "\n";
}
If I have this code
struct Unit{
int coef; //coefficient
int exp; //exponent
};
class Func: private std::list<Unit>{
public:
Func();
friend std::ostream& operator<<(std::ostream &, Func);
};
How do I print it out?
I tried using the concept from here: http://www.cplusplus.com/forum/beginner/5074/
But without success:
ostream& operator<<(ostream &output, Func &pol)
{
list<Unit>::iterator i;
for( i = pol.begin(); i != pol.end(); ++i)
{
Unit test = *i;
output << test.coef << " ";
}
return output;
}
And do I initialize it correctly?
Func::Func()
{
Unit test;
test.coef = 0;
test.exp = 0;
Func::push_back(test);
}
Sorry. New to this about inheritance. Though it wasn't hard when it was about the classes I made myself.
Updated code:
struct Unit{
int coef; //coefficient
int exp; //exponent
Unit():coef(0),exp(0){}
};
class Func : public std::list<Unit>{
public:
Func();
friend std::ostream& operator<<(std::ostream &, const Func &);
};
Func::Func()
{
Unit test;
Func::push_back(test);
}
ostream& operator <<(std::ostream &output, const Func& pol)
{
for (list<Unit>::const_iterator i = pol.begin(); i != pol.end(); output << i->coef << " " << i->exp << " ", ++i);
return output;
}
It is not clear for me what do you want to do. Is is a requirement that you inherit from an STL list? I wouldn't do it.
But this at least would be a solution.
struct Unit{
int coef; //coefficient
int exp; //exponent
};
std::ostream& operator<<(std::ostream &os, Unit const& v)
{
os << v.coef << " " << v.exp << std::endl;
return os;
}
int main()
{
std::list<Unit> myList;
Unit element;
element.coef = 0;
element.exp = 0;
myList.push_back(element);
std::ostringstream os;
for (std::list<Unit>::const_iterator it = myList.begin(); it != myList.end(); ++it)
{
os << *it;
}
std::cout << os.str() << std::endl;
}
With C++11 this could be implemented much nicer, but I don't know what compiler you are using. I did not compile it so far, just hacked it down; so sorry for syntax errors.
First, regarding your printing. You can do it a number of ways, the most robust being defining free operators for each type. Such as:
struct Unit{
int coef; //coefficient
int exp; //exponent
};
std::ostream& operator <<(std::ostream& os, const Unit& unit)
{
os << unit.coef << "X^" << unit.exp;
return os;
}
The function is a little more complex. You would be better served to use the list as a member variable and provide an operator for stream insertion for that class. Such as:
#include <iostream>
#include <iterator>
#include <list>
#include <cstdlib>
struct Unit
{
int coef; //coefficient
int exp; //exponent
Unit(int coef, int exp=0)
: coef(coef), exp(exp)
{}
friend std::ostream& operator <<(std::ostream&, const Unit&);
};
std::ostream& operator <<(std::ostream& os, const Unit& unit)
{
os << unit.coef << "X^" << unit.exp;
return os;
}
class Func
{
public:
std::list<Unit> units;
friend std::ostream& operator <<(std::ostream&, const Func&);
};
std::ostream& operator <<(std::ostream& os, const Func& func)
{
std::copy(func.units.begin(), func.units.end(),
std::ostream_iterator<Unit>(os, " "));
return os;
}
int main()
{
Func func;
func.units.push_back(Unit(3, 2));
func.units.push_back(Unit(2, 1));
func.units.push_back(Unit(1, 0));
std::cout << func << endl;
return EXIT_SUCCESS;
}
Output
3X^2 2X^1 1X^0
Note: I did NOT properly hide members, provide accessors, etc. That I leave to you, but the general idea on how to provide output-stream operators should be obvious. You could significantly further enhance the output operator for a `Unit by:
Not printing exponents of 1
Only printing the coefficient for exponents of 0 (no X),
Not printing a 1 coefficient of any term with an exponent greater than 0
Not printing anything for terms with 0 coefficients.
These tasks I leave to you.