Problem with conversion from className * to className &(and the reverse) - c++

Can someone , for the love of god please help me. I've been stuck on this for hours
This is the "father" .h file , which i am NOTallowed to alter at all
//------------ Declarations for List traits used in Test1 in main.cpp
template <typename T>
class ListTraits
{
public:
virtual unsigned int size() = 0;
virtual ListTraits& insert(const T& item) = 0;
virtual void print() = 0;
};
//------------ Declarations for List traits used in Test2 in main.cpp
template <typename T>
class ListTraitsExtended
{
public:
virtual const T* getCurrentElement() const = 0;
virtual void advance() = 0;
virtual void rewind() = 0;
};
And this is the "child" .h file ,
#include "ListTraits.h"
#include <array>
template <typename T>
class List : public ListTraits<T>
{
protected:
std::array<int, 7> data;
public:
unsigned int size() override{
return 0;
}
void print() override {
}
List & insert(const T& item) override {
return this;
}
};
Where I always get this error:
'return' cannot convert from List * to List &
If I do
return *this;
I still get errors...
What exactly am I doing wrong?I cant wrap my head around it

List& List::insert(const T &item) is declared to return a reference to List. this is a pointer to List. To return a reference to List, return *this:
List & insert(const T& item) override {
return *this;
}

Related

Multi-type container C++. Casting to derived template class

I am trying to implement a multi-type container in C++ without using std::any, std::variant, boost::any, etc. The add() function adds new objects (int, string, or other Structures) by wrapping them in the template element class and storing as Structure pointers:
using StructPtr = std::shared_ptr<Structure>;
class Structure{
public:
Structure() = default;
Structure(const Structure& oldStruct);
Structure operator = (Structure otherStruct);
bool operator == (const Structure& otherStruct);
template<class T>
void add(T obj){
elements.emplace_back(std::make_shared<Element<T>>(obj));
}
void print(std::ostream& out);
std::vector<StructPtr> elements;
};
template<class T>
class Element : public Structure{
public:
Element() = default;
Element(T _element) : element(_element) { }
Element( Element& oldElement){
element = oldElement.element;
}
T element;
};
I have a print function that takes in an element and prints it:
template<class T>
void printElement(std::ostream& out, const Element<T>& element){
printElement(out, element.element); //this functionality has been provided already.
}
I want to go through each element in the vector and pass it to this print function. However, since they are stores as StructPtrs, I do not know how to cast them into this templated Element class (I cannot use dynamic_cast).
This is what I tried:
template<class T>
void printElement(std::ostream& out, const std::vector<StructPtr>& elements){
for(auto element : elements){
auto elementDerived = static_cast<Element<T>>(*element);
printElement(out, elementDerived);
}
}
void printElement(std::ostream& out, const Structure& s){
printElement(out, s.elements);
}
But this gives an error:
no instance of overloaded function "printElement" matches the argument listC/C++(304)
task01.cpp(64, 5): argument types are: (std::__1::ostream, const std::__1::vector<StructPtr, std::__1::allocator<StructPtr>>)
So, my main question is, how do I call:
template<class T>
void printElement(std::ostream& out, const Element<T>& element)
on each element of the vector?
You can't perform a static_cast inside of printElement() since you don't know what to cast to (dynamic_cast would have helped you with that), so the only solution is to make Structure::print() be virtual and have Element override it, eg:
class Structure{
public:
...
virtual void print(std::ostream& out) const {
printElement(out, elements);
}
...
};
template<class T>
class Element : public Structure{
public:
...
void print(std::ostream& out) const override {
printElement(out, element);
}
...
};
void printElement(std::ostream& out, const std::vector<StructPtr>& elements){
for(auto element : elements){
element->print(out);
}
}

Hash Table not accepting function passed into constructor in member init list

I have a hash table template that I have written for a class. I have a project due that relies on utilizing this hash table. It accepts an unsigned integer value to initialize the number of buckets it has, as well as a hash function to point to. I have not written that hash function yet, but I have a declaration for it. When I try to use the member initializer in my Game class for the hash table data member, it gives me an error that I don't understand.
Error 1 error C3867: 'Game::xorHash': function call missing argument list; use '&Game::xorHash' to create a pointer to member
2 IntelliSense: no instance of constructor "HTable<Type>::HTable [with Type=std::string]" matches the argument list
argument types are: (int, unsigned int (const std::string &s))
my Hash Table class is as follows:
#pragma once
#include "SLList.h"
template<typename Type> class HTable
{
public:
HTable(unsigned int numOfBuckets, unsigned int (*hFunction) (const Type &v));
~HTable();
HTable<Type>& operator=(const HTable<Type>& that);
HTable(const HTable<Type>& that);
void insert(const Type& v);
bool findAndRemove(const Type& v);
void clear();
int find(const Type& v) const;
private:
SLList<Type>* ht;
unsigned int (*hFunct) (const Type &v);
unsigned int numOfBuck;
};
template<typename Type>
HTable<Type>::HTable(unsigned int numOfBuckets, unsigned int (*hFunction) (const Type &v))
{
ht = new SLList<Type>[numOfBuckets];
this->numOfBuck = numOfBuckets;
this->hFunct = hFunction;
}
template<typename Type>
HTable<Type>::~HTable()
{
delete [] ht;
ht = nullptr;
}
template<typename Type>
HTable<Type>& HTable<Type>::operator=(const HTable<Type>& that)
{
if(this != &that)
{
delete [] this->ht;
this->hFunct = that.hFunct;
this->numOfBuck = that.numOfBuck;
this->ht = new SLList<Type>[numOfBuck];
for(unsigned int i = 0; i < this->numOfBuck; i++)
this->ht[i] = that.ht[i];
}
return *this;
}
template<typename Type>
HTable<Type>::HTable(const HTable<Type>& that)
{
this = *that;
}
template<typename Type>
void HTable<Type>::insert(const Type& v)
{
ht[hFunct(v)].addHead(v);
}
template<typename Type>
bool HTable<Type>::findAndRemove(const Type& v)
{
SLLIter<Type> iter(ht[hFunct(v)]);
for(iter.begin(); !iter.end(); ++iter)
{
if(v == iter.current())
{
ht[hFunct(v)].remove(iter);
return true;
}
}
return false;
}
template<typename Type>
void HTable<Type>::clear()
{
for(unsigned int i = 0; i < this->numOfBuck; ++i)
ht[i].clear();
}
template<typename Type>
int HTable<Type>::find(const Type& v) const
{
SLLIter<Type> iter(ht[hFunct(v)]);
for(iter.begin(); !iter.end(); ++iter)
{
if(v == iter.current())
return hFunct(v);
}
return -1;
}
My Game.h:
#pragma once
#include "stdafx.h"
#include "HTable.h"
#include "BST.h"
#include "DTSTimer.h"
using namespace std;
class Game
{
public:
Game(void);
virtual ~Game(void);
void refresh();
void input();
unsigned int xorHash(const string &s);
private:
string userInput;
DTSTimer timer;
BST<string> answers;
HTable<string> dictionary;
};
My Game.cpp (this is obviously just a skeleton, since I can't get the member init to work)
#include "Game.h"
Game::Game(void) : dictionary(2048, xorHash)
{
}
Game::~Game(void)
{
}
void Game::refresh()
{
}
void Game::input()
{
}
unsigned int Game::xorHash(const string &s)
{
return 0;
}
I've been working on this for a good while, and have been hitting a wall. I would really appreciate some help on how to get this thing up and running. Let me know if there is another snippet that needs to be seen (I've tried to be thorough in that regard).
You have two problems. The first is that you don't pass the member function pointer properly (the error message tells you exactly what do do). The other problem is that a function pointer is not the same as a member function pointer.
A member function pointer needs an instance object object to call the member function on. And this instance is passed as a hidden first argument, something that normal functions don't have.
For this you might instead turn to std::function and std::bind:
class HTable
{
public:
HTable(unsigned int numOfBuckets, std::function<unsigned int(const Type&)> hFunction);
...
private:
std::function<unsigned int(const Type&)> hFunct;
...
};
Then
Game::Game(void) : dictionary(2048, std::bind(&Game::xorHash, this))
{
}

Call the cast operator of template base class within the derived class

I have a template class, called Cell, here the definition:
template <class T>
class OneCell
{
.....
}
I have a cast operator from Cell to T, here
virtual operator const T() const
{
.....
}
Now i have derived class, called DCell, here
template <class T>
class DCell : public Cell<T>
{
.....
}
I need to override the Cell's cast operator (insert a little if), but after I need to call the Cell's cast operator. In other methods it's should be something like
virtual operator const T() const
{
if (...)
{
return Cell<T>::operator const T;
}
else throw ...
}
but i got a compiler error
error: argument of type 'const int (Cell::)()const' does not match 'const int'
What can I do?
Thank you, and sorry about my poor English.
You are missing parentheses, so the compiler thought you were trying to return the member function, not call it.
return Cell<T>::operator const T();
You're not actually calling the operator:
return Cell<T>::operator const T();
Full code:
template <class T>
class OneCell
{
public:
virtual operator const T() const
{
return T();
}
};
template <class T>
class DCell : public OneCell<T>
{
public:
virtual operator const T() const
{
cout << "operator called";
return OneCell<T>::operator const T();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
DCell<int> x;
int y = (int)x;
}
Consider this code with the implementations of Cell and DCell:
#include <iostream>
#include <exception>
template<class T>
class Cell
{
protected:
T cnt;
public:
Cell(const T& cnt = T()) : cnt(cnt){}
virtual operator const T() const { return cnt; }
};
bool test_bool = true;
template<class T>
class DCell : public Cell<T>
{
public:
DCell(const T& cnt = T()) : Cell<T>(cnt){}
virtual operator const T() const
{
if(test_bool)
{
return Cell<T>::operator const T(); // Here you had Cell<T>::operator const T;
} else {
throw std::exception();
}
}
};
int main()
{
DCell<int> cell(5);
std::cout << static_cast<int>(cell) << "\n"; // prints 5 (and a new line)
return 0;
}
Don't make the operator virtual. Instead, delegate to a protected virtual helper function.
template <class T>
class Cell
{
public:
operator const T() const { return cvt_T(); }
protected:
virtual const T cvt_T() const;
};
template <class T>
class DCell : public Cell<T>
{
const T cvt_T() const
{
if (...)
{
return Cell<T>::cvt_T();
}
else throw ...
}
};
This and other good practices can be learned from GotW, here is the section on virtual architecture.

C++ abstract class template

I have the following code:
template <typename T>
class ListBase
{
protected:
int _size;
public:
ListBase() {_size=0;}
virtual ~ListBase() {}
bool isEmpty() {return (_size ==0);}
int getSize() {return _size;}
virtual bool insert(int index, const T &item) = 0;
virtual bool remove(int index) = 0;
virtual bool retrieve(int index, T &item) = 0;
virtual string toString() = 0;
};
My second file defines a subclass:
#define MAXSIZE 50
template <class T>
class ListArray : public ListBase
{//for now to keep things simple use int type only later upgrade to template
private:
T arraydata[MAXSIZE];
public:
bool insert(int index,const T &item)
{
if(index >= MAXSIZE)
return false;//max size reach
if (index<0 || index > getSize() )//index greater than array size?
{
cout<<"Invalid index location to insert"<<endl;
return false;//invalid location
}
for(int i = getSize()-1 ; i >= index;i--)
{//shift to the right
arraydata[i+1]=arraydata[i];
}
arraydata[index] = item;
_size++;
return true;
}
string ListArray::toString()
{
ostringstream ostr;
ostr<<"[";
for(int i = 0; i < _size;i++)
ostr<<arraydata[i]<<' ';
ostr<<"]"<<endl;
return ostr.str();
}
};
My main.cpp:
int main()
{
ListArray<char> myarray;
myarray.insert(0,'g');
myarray.insert(0,'e');
myarray.insert(1,'q');
cout<<myarray.toString();
}
I can't seem to figure out how to use a template with a subclass. When I compile my code, I get the following error:
error C2955: 'ListBase' : use of class template requires template argument list
see reference to class template instantiation 'ListArray' being compiled
You didn't specify the template parameter for ListBase.
template <class T>
class ListArray : public ListBase<T>
---
class ListArray : public ListBase
should be
class ListArray : public ListBase<T>
And you've got a bunch of problems with accessing the base class members. See: Accessing inherited variable from templated parent class.

C++ cannot instantiate abstract class

I am new to C++. Could you pls help me get rid of the errors:
error C2259: 'MinHeap' : cannot instantiate abstract class
IntelliSense: return type is not identical to nor covariant with return type "const int &" of overridden virtual function function
template <class T> class DataStructure {
public:
virtual ~DataStructure () {}
virtual bool IsEmpty () const = 0;
virtual void Push(const T&) = 0;
virtual const T& Top() const = 0;
virtual void Pop () = 0;
};
class MinHeap : public DataStructure<int>
{
private:
std::vector<int> A;
public:
bool IsEmpty() const
{
..
}
int Top() const
{
..
}
void Push(int item)
{
...
}
void Pop()
{
..
}
};
The problem is with const T& Top() vs. int Top(). The latter is different from the former, and thus not an override. Instead it hides the base class function. You need to return exactly the same as in the base class version: const int& Top() const.
The same problem exists for Push(), BTW.
try
class MinHeap : public DataStructure<int>
{
private:
std::vector<int> A;
public:
bool IsEmpty() const
{
..
}
const int& Top() const
{
..
}
void Push(const int& item)
{
...
}
void Pop()
{
..
}
};
Note that it is using const int& instead of int for Top and Push