class template - can't find appropriate operator method - c++

I am trying to implement own set in C++ using class templates and operators overriding.
I have following code in my MySet.h file:
#include "stdafx.h"
#pragma once
#include <iostream>
#include <string>
using namespace std;
#define DEFAULT_LEN 10
template <class T> class MySet
{
public:
MySet(int len = DEFAULT_LEN)
{
elements = new T[len];
count = 0;
}
~MySet()
{
delete elements;
}
MySet<T> operator+(T &element)
{
cout << "Some code here!"; //deleted to simplify code, the problem is that this method is not seen in main
return MySet<T>();
}
string writeSet()
{
string result = "";
for (int i = 0;i < count; i++)
{
result += elements[i] + ", ";
}
return result;
}
private:
T* elements;
int count;
};
and this in my main:
#include "stdafx.h"
#include "MySet.h"
int main()
{
MySet<int> a = MySet<int>(10);
cout << a.writeSet();
a = a + 2;
a = a + 3;
a = a + 4;
cout << a.writeSet();
return 0;
}
Unfortunately I am getting problems while compilling with this lines:
a = a + 2;
. The output is:
1>c:\path\main.cpp(11): error C2679: binary '+': no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
1> c:\path\myset.h(22): note: could be 'MySet<int> MySet<int>::operator +(T &)'
1> with
1> [
1> T=int
1> ]
How is this possible? As far as I understand it, MySet<T> operator+(T &element) should be enough because of T type. What am I missing?

It has to be:
MySet<T> operator+(const T &element)

Related

C++ operator overloading [] and return types

I'm just revisiting C++, and I have a question about overloading of the [] operator, and more specifically why my program doesn't work.
Given the following code in vec.cpp:
double Vec::operator[](unsigned int i) const {
return this->values[i];
}
double & Vec::operator[](unsigned int i) {
return this->values[i];
}
These are defined in vec.h as methods to the Vec class, and if I do not use the operator in my main.cpp, all is fine and dandy. It compiles just as normal with no errors.
However once I do this in my main function (which is using std::cout and std::endl):
cout << a[0] << endl;
Things go wrong. The errors I get are a bunch of
candidate function template not viable: no known conversion from 'Vec' to 'char' for 2nd argument
operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)
where you can replace 'char' with any primitive data type.
Here is a working example
// In vec.h
#pragma once
#include <string>
#include <iostream>
class Vec {
private:
int dims;
double *values;
public:
Vec(int dims, double values[]);
double operator [](unsigned int i) const;
double& operator[](unsigned int i);
};
// In vec.cpp
#include <iostream>
#include <string>
#include <cmath>
#include "vec.h"
using std::cerr, std::endl, std::cout;
Vec::Vec(int dims, double values[]) {
this->dims = dims;
this->values = new double[dims];
for(int i = 0; i < dims; i++) {
this->values[i] = values[i];
}
}
double Vec::operator[](unsigned int i) const {
if(i >= this->dims) {
cerr << "Elem out of range" << endl;
}
return this->values[i];
}
double & Vec::operator[](unsigned int i) {
if(i >= this->dims) {
cerr << "Elem out of range" << endl;
}
return this->values[i];
}
// In main.cpp
#include <iostream>
#include <string>
#include "vec.h"
using std::cout, std::endl;
int main() {
double avals[2];
avals[0] = 1.0;
avals[1] = 2.0;
Vec *a = new Vec(2, avals);
cout << a[0] << endl; // Error occurs here
return 0;
}
Can anyone help me sort this out?
In this declaration
Vec *a = new Vec(2, avals);
there is declared a pointer of the type Vec *. So an expression with the dereferenced pointer has the type Vec.
So in this statement
cout << a[0] << endl;
the expression a[0] has the type Vec.
It seems you mean
( *a )[0]
or
a[0][0]

Function Pointer for C++

I am studying C++ on Essential C++ by lippman. Here is some code where two lines contain error while I don't know why it's happening and how to fix it.
#include "stdafx.h"
#include <vector>
#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;
const vector<int>* fibon_seq(int size) {
const int max_size = 1024;
static vector<int> elems;
if (size <= 0 || size > max_size) {
cerr << "Error";
return 0;
}
for (int ix = elems.size(); ix < size; ++ix) {
if (ix == 0 || ix == 1)
elems.push_back(1);
else elems.push_back(elems[ix - 1] + elems[ix - 2]);
}
return &elems;
}
void display(const vector<int>* vec, ostream &os = cout) {
if (!vec)
cerr << "null vector";
for (int i = 0; i < (vec)->size(); ++i)
os << (*vec)[i] << " ";
os << endl;
}
bool fibon_elem(int pos, int &elem, const vector<int>* (*seq_ptr)(int)) {
const vector<int> *pseq = seq_ptr(pos);
if (!pseq){
elem = 0; return false;
}
elem = (*pseq)[pos - 1];
return true;
}
int main()
{
const vector<int>* (*(*seq_array)[1])(int);
(*seq_array)[0] = fibon_seq;
vector<int>* (*seq_ptr)(int);
int seq_index = 0;
seq_ptr = (*seq_array)[0];//This is the line with error.
//(a value of type "const std::vector<int, std::allocator<int>> *(*)(int)"
//cannot be assigned to an entity of type "std::vector<int, std::allocator<int>>
//*(*)(int)"
//C2440 '=': cannot convert from 'const std::vector<int,std::allocator<_Ty>>
//*(__cdecl *)(int)' to 'std::vector<int,std::allocator<_Ty>>
//*(__cdecl *)(int)'
int a;
fibon_elem(12, a, seq_ptr);//This is the line with error.
//argument of type "std::vector<int, std::allocator<int>> *(*)(int)"
//is incompatible with parameter of type "const std::vector<int, std::allocator<int>>
//*(*)(int)"
//C2664 'bool fibon_elem(int,int &,const std::vector<int,std::allocator<_Ty>>
//*(__cdecl *)(int))': cannot convert argument 3 from 'std::vector<int,std::allocator<_Ty>>
//*(__cdecl *)(int)' to 'const std::vector<int,std::allocator<_Ty>>
//*(__cdecl *)(int)' test
getchar();
return 0;
}
For the first line in error, I make both sides of the equation the same type, while the compiler says that the value cannot be assigned. For the second line in error, the two same type are incompatible with each other.
And the error message given by compiler is the following:
Your function fibon_seq returns a const vector<int>*, and you're trying to assign it to a vector<int>* which is seq_ptr. Change seq_ptr to a const vector<int>* or change the return type of fiber_seq.

Deleting an element from vector of type structure

I am trying this piece of code. What I am trying to do is to delete an element from vector of type structure
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/bind.hpp>
using namespace std;
typedef struct _detail
{
int y;
}detail;
typedef struct _list
{
int x;
detail det;
}list;
std::vector<list> v;
list li[5];
void PushElements()
{
for(int i = 0; i < 5; i++)
{
li[i].x = i+2;
li[i].det.y = i+3;
v.push_back(li[i]);
}
}
void display()
{
for(int i = 0; i < v.size(); i++)
{
cout << v[i].x << " ";
cout << v[i].det.y << " ";
}
cout << endl;
}
void DeleteElement()
{
std::vector<list>::iterator it = std::find_if(v.begin(), v.end(), boost::bind(&list::detail::y, _1) == 3);
v.erase(it);
}
int main()
{
PushElements();
display();
DeleteElement();
cout << "After Deleting...................." << endl;
display();
return 0;
}
While compiling I get following errors:
error C3083: 'detail': the symbol to the left of a '::' must be a type
error C2039: 'y' : is not a member of '_list'
error C2065: 'y' : undeclared identifier
I don't understand what this error is and how to solve it. Can somebody help me to solve this error??
&list::detail::y
detail is the name of a type that isn't nested in list. list has a member of type detail named y.
I think you want to form a pointer to member of member, but as far as I can tell, it's not possible. You're better off using a lambda to do the comparisons. Something like:
std::find_if(..., ..., [something](const list& l) { return l.det.y == something; } );
On another note, identifiers beginning with an underscore are reserved in the global namespace. _list and _detail aren't strictly allowed.

Template with Inheritance C++

Using inheritance and templates, Ive to sort by name an array of employee information. I got three classes, Payroll, SimpleVector and SortingVector. Payroll contains all the user info attributes, SimpleVector creates a dynamic array of type Payroll to store all the user info. Now do SortingVector class is in charge of sorting the array by names. But I keep getting many different errors whenever I tried to fix a previous error.
Posting now each class:
Payroll class
#pragma once
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Payroll {
private:
int empNumber;
string name;
double hours;
double payRate;
double grossPay;
int *aptr;
int arraySize;
public:
Payroll(int size);
Payroll();
Payroll(const Payroll & aPayroll);
~Payroll();
//Mutators
void setVector(Payroll &aPayroll);
void setEmpNumber(int empNumber);
void setName(string name);
void setHours(double hours);
void setPayRate(double payRate);
void setGrossPay(double grossPay);
//Accessors
int getEmpNumber()const;
string getName()const;
double getHours()const;
double getPayRate()const;
double getGrossPay()const;
Payroll &operator =(const Payroll &aPayroll);
bool operator ==(const Payroll &aPayroll) const;
friend ostream & operator << (ostream & output, const Payroll & aPayroll);
friend istream & operator >> (istream & input, Payroll & aPayroll);
};
//cpp
Payroll::Payroll() : empNumber(0), name(""), hours(0.00), payRate(0.00), grossPay(0.00) {}
Payroll::Payroll(const Payroll & aPayroll) : empNumber(aPayroll.empNumber), name(aPayroll.name), hours(aPayroll.hours),
payRate(aPayroll.payRate), grossPay(aPayroll.grossPay) {}
Payroll::~Payroll() {
}
//Mutators
void Payroll::setEmpNumber(int empNumber) {
this->empNumber = empNumber;
}
void Payroll::setName(string name) {
this->name = name;
}
void Payroll::setHours(double hours) {
this->hours = hours;
}
void Payroll::setPayRate(double payRate) {
this->payRate = payRate;
}
void Payroll::setGrossPay(double grossPay) {
this->grossPay = grossPay;
}
//Accessors
int Payroll::getEmpNumber()const {
return(this->empNumber);
}
string Payroll::getName()const {
return(this->name);
}
double Payroll::getHours()const {
return(this->hours);
}
double Payroll::getPayRate()const {
return(this->payRate);
}
double Payroll::getGrossPay()const {
return(this-> hours * payRate);
}
Payroll &Payroll::operator = (const Payroll &aPayroll) {
this->name = aPayroll.name;
this->empNumber = aPayroll.empNumber;
this->hours = aPayroll.hours;
this->payRate = aPayroll.payRate;
this->grossPay = aPayroll.grossPay;
return(*this);
}
bool Payroll::operator ==(const Payroll &aPayroll) const {
bool equal = this->name == aPayroll.name;
return(equal);
}
SIMPLEVECTOR CLASS
#ifndef SIMPLEVECTOR_H
#define SIMPLEVECTOR_H
#include <iostream>
#include <cstdlib>
#include "C:\Users\Jorge\Dropbox\PayRoll Class\Payroll.h"
using namespace std;
template <class type>
class SimpleVector {
private:
type *aptr;
int arraySize;
void subError();
public:
SimpleVector(int);
SimpleVector(const SimpleVector &aVector);
~SimpleVector();
int size() {
return arraySize;
}
type &operator [](int);
void print();
};
template <class type>
SimpleVector<type>::SimpleVector(int s) {
arraySize = s;
aptr = new type[s];
for (int count = 0; count < arraySize; count++)
aptr[count] = type();
}
template <class type>
SimpleVector<type>::SimpleVector(const SimpleVector &aVector) {
arraySize = aVector.arraySize;
aptr = new type[arraySize];
for (int count = 0; count < arraySize; count++)
aptr[count] = aVector[count];
}
template <class type>
SimpleVector<type>::~SimpleVector(){
if (arraySize > 0)
delete[] aptr;
}
template <class type>
void SimpleVector<type>::subError() {
cout << "ERROR: Subscript out of range.\n";
exit(0);
}
template <class type>
type &SimpleVector<type>::operator[](int sub) {
if (sub < 0 || sub >= arraySize)
subError();
return aptr[sub];
}
template <class type>
void SimpleVector<type>::print() {
for (int k = 0; k < arraySize; k++)
cout << aptr[k] << " ";
cout << endl;
}
#endif
SORTINGARRAY CLASS
#ifndef SortingVector_h
#define SortingVector_h
#include "SimpleVector.h"
#include <iostream>
#include <string>
template <class t>
class SortingVector : public SimpleVector<t> {
public:
SortingVector(int s) : SimpleVector<t>(s) {}
SortingVector(SortingVector &aSort);
SortingVector(SimpleVector<t> &aVector) : SimpleVector<t>(aVector) {}
void sortingByName(SimpleVector<Payroll> &aVector);
};
#endif
template <class t>
SortingVector<t>::SortingVector(SortingVector &aVector) : SimpleVector<t>(aVector) {}
template <class t>
void SortingVector<t>::sortingByName(SimpleVector<Payroll> &aVector) {
bool swap;
SortingVector<Payroll> temp;
int x;
do {
swap = false;
for (int i = 0; i < aVector.arraySize; i++) {
x = strcmp(aVector[i], aVector[i + 1]);
if (x > 0) {
temp = aVector[i];
aVector[i] = aVector[i + 1];
aVector[i + 1] = temp;
swap = true;
}
}
} while (swap);
}
The errors right now are:
Error 2 error C2248: 'SimpleVector<Payroll>::arraySize' : cannot access private member declared in class 'SimpleVector<Payroll>' c:\users\jorge\dropbox\simplevector\simplevector\sortingvector.h 39 1 SimpleVector
Error 1 error C2512: 'SortingVector<Payroll>' : no appropriate default constructor available c:\users\jorge\dropbox\simplevector\simplevector\sortingvector.h 32 1 SimpleVector
Error 3 error C2664: 'int strcmp(const char *,const char *)' : cannot convert argument 1 from 'Payroll' to 'const char *' c:\users\jorge\dropbox\simplevector\simplevector\sortingvector.h 42 1 SimpleVector
Error 4 error C2679: binary '=' : no operator found which takes a right-hand operand of type 'Payroll' (or there is no acceptable conversion) c:\users\jorge\dropbox\simplevector\simplevector\sortingvector.h 45 1 SimpleVector
Error 5 error C2679: binary '=' : no operator found which takes a right-hand operand of type 'SortingVector<Payroll>' (or there is no acceptable conversion) c:\users\jorge\dropbox\simplevector\simplevector\sortingvector.h 47 1 SimpleVector
SortingVector<Payroll> temp(); is not parsed as you expected (vexing parse), you want:
SortingVector<Payroll> temp;
or
SortingVector<Payroll> temp{}; /* since C++11 */

Declaring the templates in c++

// stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <iostream>
using namespace std;
#include "Animal.h"
// TODO: reference additional headers your program requires here
class Animal
{
private:
int itsWeight;
public:
Animal(int);
Animal();
~Animal() {}
int getWeight() const { return itsWeight; }
void Display() const;
};
template <class T>
class Array
{
private:
T *pType;
int itsSize;
const int defaultSize = 10;
public:
//constructors
Array(int itsSize = defaultSize);
Array(const Array &rhs);
~Array() { delete[] pType; }
//operators
Array& operator=(const Array&);
T& operator[](int offSet){ return pType[offSet]; }
const T& operator[](int offSet) const { return pType[offSet]; }
//methods of Access
int getSize() const { return itsSize; }
};
//constructor
template <class T>
Array<T>::Array(int size) :
itsSize(size)
{
pType = new T[size];
for (int i = 0; i < size; i++)
{
pType[i] = 0;
}
}
//copy-constructor
template <class T>
Array<T>::Array(const Array &rhs)
{
itsSize = rhs.getSize();
pType = new T[itsSize];
for (int i = 0; i < itsSize; i++)
{
pType[i] = rhs[i];
}
}
//operator prisvoeniya
template <class T>
Array<T>& Array<T>::operator=(const Array &rhs)
{
if (this == &rhs)
return *this;
delete[] pType;
itsSize = rhs.getSize();
pType = new T[itsSize];
for (int i = 0; i < itsSize; i++)
{
pType[i] = rhs[i];
}
return *this;
}
//this is the file "Animal.cpp"
#include "stdafx.h"
#include "Animal.h"
Animal::Animal()
{
itsWeight = 0;
}
Animal::Animal(int weight)
{
itsWeight = weight;
}
void Animal::Display() const
{
cout << itsWeight;
}
// the main function
#include "stdafx.h"
int_tmain(int argc, _TCHAR* argv[])
{
Array<int> theArray; //Integer array
Array<Animal> theZoo; //Animal array
Animal *pAnimal;
//filling the array
for (int i = 0; i < theArray.getSize(); i++)
{
theArray[i] = i * 2;
pAnimal = new Animal[i * 3];
theZoo[i] = *pAnimal;
delete pAnimal;
}
for (int j = 0; j < theArray.getSize(); j++)
{
cout << "theArray[" << j << "]:\t";
cout << theArray[j]<<"\t\t";
cout << "theZoo[" << j << "]:\t";
theZoo[j].Display();
cout << endl;
}
return 0;
}
The problem is that: The compiler gives me the errors
Error 1 error C2648: 'Array<int>::defaultSize' : use of member as default parameter requires static member
d:\documents\work\c++ files\tigrans\homework10\templates\templates\templates\animal.h 28 1 Templates
Error 2 error C2648: 'Array<Animal>::defaultSize' : use of member as default parameter requires static member
d:\documents\work\c++ files\tigrans\homework10\templates\templates\templates\animal.h 28 1 Templates
Anybody can help me to understand that. I change the
const int defaultSize=10;
to
static const int defaultSize=10
then there is not errors but in that time show Debug Assertion Failed!
This part of your code is dodgy
{
pAnimal = new Animal[i * 3];
theZoo[i] = *pAnimal;
delete pAnimal;
}
The first line allocates an array of i*3 Animals, using their default constructor (which makes an Animal with itsWeight=0). In the second line you assign the first these newly allocated Animals to theZoo[i]. Finally, the third line tries to de-allocate the Animals.
The last line contains an error, since you call delete on a pointer obtained with new [].
The whole concept of creating objects on the heap only to immediately destroy them is quite dubious -- perhaps you come from another programming language, where this is the only way to create things? First, you could simply use an automatic variable
{
Animal a; // or a(i*3);
theZoo[i] = a;
}
or yet briefer
{
theZoo[i] = Animal(i*3);
}
(Note the if you would use a std container, you could say theZoo.emplace_back(i*3);, avoiding the copy of Animal.)