iterator on map of pointers to objects as a key c++ - c++

i'm implementing a backtracking algorithm to solve sudokus, but i have some issues using maps.
could any one tell me why i get these two errors when compiling my code? the first error is about the line declaring the iterator on the map. the second one is when doing Adj[&node] = mList;
the errors:
Error C2664 'std::_Tree_const_iterator>>> std::_Tree>::find(Node *const &) const' : can't convert argument 1 from 'const Node *' to 'Node *const &'
Error C2679 '[' binary : no operator found accepting a right operand of type 'const Node *' (ou there's no acceptable conversion)
(my Visual studio is in french, so i translated the error messages. hope it's fine like this)
my code where i got the error:
template<class T>
void AdjList<T>::addElement(const Node<T>& node, const vector<Node<T>>& vecOfNeighbours) {
typename map< Node<T>*, LinkedList<T>>::iterator mit = Adj.find(&node);
if (mit!=Adj.end()) {
LinkedList<T> mList;
for (typename vector<Node<T>>::const_iterator it = vecOfNeighbours.begin(); it != vecOfNeighbours.end(); it++) {
mList.Add((*it).getValue()[0]);
}
Adj[&node] = mList;
}
}
my classes définitions :
template<class T>
class AdjList
{
private:
map<Node<T>*, LinkedList<T>> Adj;
public:
AdjList();
AdjList(const AdjList<T>& adjlist);
AdjList(const Node<T>& node, const vector<Node<T>>& vecOfNeighbours);
void addElement(const Node<T>& node, const vector<Node<T>>& vecOfNeighbours);
void Print() const;
};
template<class T>
class LinkedList
{
Node<T>* head;
int getEndList();
Node<T>* returnFrontEnd(void) const;
public:
LinkedList();
LinkedList(T data);
LinkedList(const LinkedList<T>& list);
LinkedList<T>& operator=(const LinkedList<T>& list);
void Add(T data);
void AddAt(int index, T data);
void Print();
~LinkedList();
};
template<class T>
class Node
{
protected:
vector<T> _value;
Node<T>* child;
public:
Node(T value);
void addValue(T value);
Node<T>* clone() const;
Node(const Node<T>& node);
vector<T> getValue() const;
Node<T>* returnChild() const;
void AddChild(const Node<T>& node);
Node& operator=(const Node<T>& node);
~Node();
};

You need to cast away const. Why? Take a look:
void AdjList<T>::addElement(const Node<T>& node, const vector<Node<T>>&)
Okay, so node is a const reference,
typename map< Node<T>*, LinkedList<T>>::iterator mit = Adj.find(&node);
But this iterator will have a non-const pointer. So if this were allowed, you'd be able to get a non-const pointer from a const reference. That clearly requires casting away const (which you don't do).

Related

Operator overload template

I'm trying to implement an operator overload function based on a header file that was given to me, but I'm not understanding one this. Here's what I've been given:
template<class Type>
myClass<Type>& myClass<Type>::operator =(const myClass<Type> &);
My question is in relation to the parameter passed. (const myClass &) indicate a value passed, but how to I reference that value within the function? Normally if I have (const myClass &myValue), I would reference that with myValue=whatever. But I'm not sure how to handle this one.
This is the header file that i'm trying to implement. I'm not asking for anyone to solve this, but I would like some clarifications:
template<class Type>
struct nodeType{
Type value;
nodeType<Type> *next;
nodeType<Type> *prev;
};
template <class Type>
class sortedListADT {
public:
const sortedListADT<Type>& operator=(const sortedListADT<Type> &);
bool isEmpty() const;
bool search(const Type& searchElem) const;
void removeElement(const Type& remElem);
void insertElement(const Type& newElem);
Type front() const;
Type back() const;
void printInOrder() const;
void printRevOrder() const;
void destroyList();
sortedListADT();
sortedListADT(const sortedListADT<Type>& otherList);
~sortedListADT();
private:
nodeType<Type> *first;
nodeType<Type> *last;
int numElements;
void copyList(const sortedListADT<Type>& otherList);
};
how to I reference that value within the function?
We just can't because the parameter is unnamed and for us to use it inside the function it must have a name(to refer to it by that name).
It seems that you're trying to implement the overloaded operator= which you can do as shown below:
template <class Type>
class sortedListADT {
public:
//this is a declaration
const sortedListADT<Type>& operator=(const sortedListADT<Type> &);
//other code as before
};
template<typename Type>
//-----------------------------------------------------------------------------------vvvvvvvvvvvvv--->added a name for the paramter
const sortedListADT<Type>& sortedListADT<Type>::operator=(const sortedListADT<Type> &namedParameer)
{
//add your code here
//don't forget to have a return statement here
}
Working demo

C++ Virtual Destructor with Unresolved externals [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 4 years ago.
I have two classes..
template <class T>
class Node
{
protected:
Node() = default;
virtual ~Node() = 0;
Node(const T& data) noexcept;
Node(const Node<T> & copy) noexcept;
Node(Node<T> && copy) noexcept;
Node<T> & operator=(const Node<T> & rhs) noexcept;
Node<T> & operator=(Node<T> && rhs) noexcept;
public:
T & GetData() noexcept;
T GetData() const noexcept;
void SetData(const T & data) noexcept;
private:
T data_;
};
template<class T>
class ListNode : public Node<T>
{
public:
ListNode() = default;
ListNode(const T& data, ListNode<T> * next = nullptr, ListNode<T> * previous = nullptr) noexcept;
ListNode(const ListNode<T> & copy) noexcept;
ListNode(ListNode<T> && copy) noexcept;
~ListNode() override = default;
ListNode<T> & operator=(const ListNode<T> & rhs) noexcept;
ListNode<T> & operator=(ListNode<T> && rhs) noexcept;
ListNode<T> * GetNext() noexcept;
ListNode<T> * GetPrevious() noexcept;
void SetNext(ListNode<T> * const next) noexcept;
void SetPrevious(ListNode<T> * const previous) noexcept;
private:
ListNode<T> * next_;
ListNode<T> * previous_;
};
I get an "1 unresolved externals" error. In my previous experience this would usually mean something is wrong with virtual, override, or something like that. I've messed around with this code but can't make the error go away. Any advice?
Derived destructors always implicitly invoke the base destructor at the end of their execution. You have code that is trying to invoke an abstract function. You need to give ~Node() a definition with an empty function body:
virtual ~Node() {};

how to write a default iterator to a generic list?

i am writing this code a generic list , now in this generic list i did a class for iterator that helds two parameters : one is a pointer to the list he points to .
and the other one points to the element in the list he points to ..
now i need to write an insert function that inserts a new element to a given list , with the following rules :: where i insert a new node to the list, and in this function if the iterator poiints to the end of the list the we add the new node to the end of the list else we insert the node one place before the node that the iterator currently points to , and if the iteratot points to a different node then thats an error .
now i want the iterator to be defoult so in case in the tests someone called the function with one parameter i want the iterator to be equal to the end element of the list.
the function end i wrote it inside of the list.
now in the insert function i did that but i get this error :
cannot call member function "List::iterator List::end()"without object
.
#include <iostream>
#include <assert.h>
#include "Exceptions.h"
template <class T>
class List {
public:
List();
List(const List&);
~List();
List<T>& operator=(const List& list);
template <class E>
class ListNode {
private:
ListNode(const E& t, ListNode<E> *next): data(new E(t)), next(next){}
~ListNode(){delete data;}
E* data;
ListNode<E> *next;
public:
friend class List<E>;
friend class Iterator;
E getData() const{
return *(this->data);
}
ListNode<E>* getNext() const{
return this->next;
}
};
class Iterator {
const List<T>* list;
int index;
ListNode<T>* current;
Iterator(const List<T>* list, int index): list(list),
index(index),current(NULL){
int cnt=index;
while (cnt > 0) {
current = current->next;
cnt--;
}
}
friend class List<T>;
friend class ListNode<T>;
public:
// more functions for iterator
};
Iterator begin() const ;
Iterator end() const;
void insert(const T& data, Iterator iterator=end());//here i get the error
void remove(Iterator iterator);
class Predicate{
private:
T target;
public:
Predicate(T i) : target(i) {}
bool operator()(const T& i) const {
return i == target;
}
};
Iterator find(const Predicate& predicate);
class Compare{
private:
T target;
public:
Compare(T i) : target(i) {}
bool operator()(const T& i) const {
return i < target;
}
};
bool empty() const;
int compareLinkedList(ListNode<T> *node1, ListNode<T> *node2);
private:
ListNode<T> *head;
ListNode<T> *tail;
int size;
};
any help would be amazing ! cause i don't know why such a mistake apears .
//insert function just in case :
template <typename T>
void List<T>::insert(const T& data, Iterator iterator=end()){
if(iterator.list!=this){
throw mtm::ListExceptions::ElementNotFound();
return;
}
ListNode<T> *newNode = new ListNode<T>(data, iterator.current);
if(iterator.index==size){
if (head == NULL) {
head = newNode;
tail=newNode;
}else{
Iterator temp(this,size-1);
temp.current->next=newNode;
}
//newNode->next=this->end().current;
}
else {
if (head == NULL) {
head = newNode;
tail=newNode;
}
else {
Iterator temp1(this,iterator.index-1);
temp1.current->next=newNode;
newNode->next=iterator.current->next;
}
}
size++;
}
void insert(const T& data, Iterator iterator=end());
This is the offending line. A default argument cannot be the result of a member function call. The right tool to achieve what you want is overloading.
void insert(const T& data, Iterator iterator);
void insert(const T& data) { insert(data, end()); }
Here we still defer to the insert function you implemented, but we call end from within the overloads body, where it's allowed.
Don't worry about the indirect call. This is a very small function that's defined inside the class declaration itself. Any decent compiler will inline it completely.

Trouble with begin() of my Map realization

help me with figuring out please why I have this error:
error:
<function-style-cast>: The compiler cannot cast from "const mtm::Node<mtm::MtmMap<int,int,std::less<KeyType>>::Pair> *" to "mtm::MtmMap<int,int,std::less<KeyType>>::iterator"
Those are different relevant parts of the code:
Node:
template <typename DataType>
class Node {
public:
DataType data;
Node<DataType> *head;
Node<DataType> *next;
public:
Node(const DataType& data) :data(data), head(nullptr) {
next = nullptr;
};
Iterator:
class iterator {
private:
Node<Pair>* _ptr = nullptr;
public:
iterator(Node<Pair>* ptr = nullptr) : _ptr(ptr) { }
iterator(const iterator& itr) = default;
~iterator() = default;
iterator& operator=(const iterator&) = default;
Private of MtmMap:
private:
Node<Pair> _pairs;
iterator _it;
int _size;
The code when the error shows:(in body of MtmMap)
iterator begin() const{
if (this->_size) {
this->_it = iterator(&_pairs);
}
return this->_it;
}
The problem is that you've declared begin as const. Thus this in this line:
this->_it = iterator(&_pairs);
&_pairs has resulting type of const Node<Pair>*. Your iterator class only accepts a non-const pointer to Node<Pair> (implicit conversion from a const-pointer to a non-const-pointer is not allowed).
Either iterator needs to be modified to accept (and store) a const-pointer, or begin needs to drop the const qualifier.

linked list operator overloading issue

i tried to build up my own linked list class and got a problem with the = operator overloading. as far as i know, we should use const parameter when overloading the assignment operator, say using linked_list<T>& operator=( const linked_list<T>& a). however, the complier gave me errors unless i put linked_list<T>& a instead. the complier would stop at
if(this->head==a.front()), giving me Error
11 error C2662: 'linked_list<T>::front' : cannot convert 'this' pointer from 'const linked_list<T>' to 'linked_list<T> &'
below are the details.
#ifndef _LINKED_LIST_H_
#define _LINKED_LIST_H_
template <class T>
struct node
{
T data;
node<T>* next;
};
template <class T>
class linked_list
{
private:
node<T>* head;
public:
linked_list<T>();
linked_list<T>(const linked_list<T>& a);
~linked_list<T>();
linked_list<T>& operator=(const linked_list<T>& a);
bool isEmpty();
int size() const;
void insert_front(T a);
void insert_end(T a);
void erase_end();
void erase_front();
void print() const;
void erase(node<T>* a);
node<T>*& front()
{
node<T>* ptr = new node<T>;
ptr = head;
return ptr;
}
void setFront(node<T>* a);
};
#endif
template <class T>
linked_list<T>& linked_list<T>::operator=(const linked_list<T>& a)
{
if (this->head == a.front()) // the error mentioned happened here. however,
// if no const in the parameter, it would be
// no error
{
return *this;
}
while (head != nullptr) erase_front();
node<T>* copy;
copy = a.front();
while (copy->next != nullptr)
{
insert_end(copy->data);
copy = copy->next;
}
return *this;
}
anybody can help? thanks.
When an accessor returns a reference to an owned structure, it's usually a good idea to implement two versions: One which is non-const and returns a non-const reference, and one which is const and returns a const reference. That way it can be used in both mutating and non-mutating contexts. front() would be a good candidate for this.
Though a side note -- you probably don't want to expose your nodes in the public linked_list interface, particularly non-const references to them. That's the sort of thing to encapsulate entirely in the class.
The problem is that front() is not a const member function, and you're trying to call it on a const instance.