samedi 24 avril 2021

In template: no matching function for call to 'swap'

I am writing a a copy constructor and a copy assignment operator for linkedlist. I have finished the code. But when I try to test the copt assignment operator, I got this error message: In template: no matching function for call to 'swap'. What is wrong with my code? And How should I fix them? I already have a Node.cpp implemented:

/** @file Node.cpp
    Listing 4-2 */
#include "Node.h"

template<class ItemType>
Node<ItemType>::Node() : next(nullptr)
{
} // end default constructor

template<class ItemType>
Node<ItemType>::Node(const ItemType& anItem) : item(anItem), next(nullptr)
{
} // end constructor

template<class ItemType>
Node<ItemType>::Node(const ItemType& anItem, Node<ItemType>* nextNodePtr) :
        item(anItem), next(nextNodePtr)
{
} // end constructor

template<class ItemType>
void Node<ItemType>::setItem(const ItemType& anItem)
{
    item = anItem;
} // end setItem

template<class ItemType>
void Node<ItemType>::setNext(Node<ItemType>* nextNodePtr)
{
    next = nextNodePtr;
} // end setNext

template<class ItemType>
ItemType Node<ItemType>::getItem() const
{
    return item;
} // end getItem

template<class ItemType>
Node<ItemType>* Node<ItemType>::getNext() const
{
    return next;
} // end getNext

Then I have a ListInterface:

/** Interface for the ADT list
    Listing 8-1
    @file ListInterface.h */

#ifndef LIST_INTERFACE_
#define LIST_INTERFACE_

template<class ItemType>
class ListInterface
{
public:
    /** Sees whether this list is empty.
     @return  True if the list is empty; otherwise returns false. */
    virtual bool isEmpty() const = 0;

    /** Gets the current number of entries in this list.
     @return  The integer number of entries currently in the list. */
    virtual int getLength() const = 0;

    /** Inserts an entry into this list at a given position.
     @pre  None.
     @post  If 1 <= position <= getLength() + 1 and the insertion is
        successful, newEntry is at the given position in the list,
        other entries are renumbered accordingly, and the returned
        value is true.
     @param newPosition  The list position at which to insert newEntry.
     @param newEntry  The entry to insert into the list.
     @return  True if the insertion is successful, or false if not. */
    virtual bool insert(int newPosition, const ItemType& newEntry) = 0;

    /** Removes the entry at a given position from this list.
     @pre  None.
     @post  If 1 <= position <= getLength() and the removal is successful,
        the entry at the given position in the list is removed, other
        items are renumbered accordingly, and the returned value is true.
     @param position  The list position of the entry to remove.
     @return  True if the removal is successful, or false if not. */
    virtual bool remove(int position) = 0;

    /** Removes all entries from this list.
     @post  The list contains no entries and the count of items is 0. */
    virtual void clear() = 0;

    /** Gets the entry at the given position in this list.
     @pre  1 <= position <= getLength().
     @post  The desired entry has been returned.
     @param position  The list position of the desired entry.
     @return  The entry at the given position. */
    virtual ItemType getEntry(int position) const = 0;

    /** Replaces the entry at the given position in this list.
     @pre  1 <= position <= getLength().
     @post  The entry at the given position is newEntry.
     @param position  The list position of the entry to replace.
     @param newEntry  The replacement entry.
     @return  The replaced entry. */
    virtual ItemType replace(int position, const ItemType& newEntry) = 0;

    /** Destroys this list and frees its assigned memory. */
    virtual ~ListInterface() { }
}; // end ListInterface
#endif

and the LinkedList.cpp

#include "LinkedList.h"
#include <stdexcept>
#include <iostream>
#include <assert.h>
#include <algorithm>

template<class ItemType>
LinkedList<ItemType>::LinkedList() : headPtr(nullptr), itemCount(0)
{
} // end default constructor

template<class ItemType>
LinkedList<ItemType>::LinkedList(const LinkedList<ItemType>& aList)
{
    itemCount = aList->itemCount;
    Node<ItemType>* origPtr = aList->headPtr;

    if (origPtr == nullptr)
        headPtr = nullptr;
    else {
        headPtr = new Node<ItemType>();
        headPtr->setItem(origPtr->getItem());

        Node<ItemType>* newPtr = headPtr; //Last node pointer
        while (origPtr != nullptr) {
            origPtr = origPtr->getNext();   // advance pointer
            ItemType nextItem = origPtr->getItem(); // get next item
            // create a new node containing the next item
            Node<ItemType>* newNodePtr = new Node<ItemType>(nextItem);

            newPtr->setNext(newNodePtr); // link new node to last
            newPtr = newPtr->getNext(); //advance pointer
        }
        newPtr->setNext(newPtr); // connect null to last
    }
}

template<class ItemType>
LinkedList<ItemType>& LinkedList<ItemType>::operator=(const
        LinkedList<ItemType>& aList) {
    std::swap(headPtr, aList.headPtr);
    return *this;
}

template<class ItemType>
void LinkedList<ItemType>::clear()
{
    while (!isEmpty())
        remove(1);
} // end clear

template<class ItemType>
LinkedList<ItemType>::~LinkedList()
{
    clear();
} // end destructor

template<class ItemType>
bool LinkedList<ItemType>::isEmpty() const
{
    return itemCount == 0;
}  // end isEmpty

template<class ItemType>
int LinkedList<ItemType>::getLength() const
{
    return itemCount;
}  // end getLength

template<class ItemType>
ItemType LinkedList<ItemType>::getEntry(int position) const
{
    // Enforce precondition
    bool ableToGet = (position >= 1) && (position <= itemCount);
    if (ableToGet)
    {
        Node<ItemType>* nodePtr = getNodeAt(position);
        return nodePtr->getItem();
    }
    else
    {
        std::string message = "getEntry() called with an empty list or ";
        message = message + "invalid position.";
        throw(std::invalid_argument(message));
    } // end if
} // end getEntry

template<class ItemType>
Node<ItemType>* LinkedList<ItemType>::getNodeAt(int position) const
{
    // Debugging check of precondition
    assert( (position >= 1) && (position <= itemCount) );

    // Count from the beginning of the chain
    Node<ItemType>* curPtr = headPtr;
    for (int skip = 1; skip < position; skip++)
        curPtr = curPtr->getNext();

    return curPtr;
}  // end getNodeAt

template<class ItemType>
bool LinkedList<ItemType>::insert(int newPosition, const ItemType& newEntry)
{
    bool ableToInsert = (newPosition >= 1) && (newPosition <= itemCount + 1);
    if (ableToInsert)
    {
        // Create a new node containing the new entry
        auto* newNodePtr = new Node<ItemType>(newEntry);
        // Attach new node to chain
        if (newPosition == 1)
        {
            // Insert new node at beginning of chain
            newNodePtr->setNext(headPtr);
            headPtr = newNodePtr;
        }
        else
        {
            // Find node that will be before new node
            Node<ItemType>* prevPtr = getNodeAt(newPosition - 1);

            // Insert new node after node to which prevPtr points
            newNodePtr->setNext(prevPtr->getNext());
            prevPtr->setNext(newNodePtr);
        } // end if

        itemCount++; // Increase count of entries
    }  // end if

    return ableToInsert;
}  // end insert

template<class ItemType>
bool LinkedList<ItemType>::remove(int position)
{
    bool ableToRemove = (position >= 1) && (position <= itemCount);
    if (ableToRemove)
    {
        Node<ItemType>* curPtr = nullptr;
        if (position == 1)
        {
            // Remove the first node in the chain
            curPtr = headPtr; // Save pointer to node
            headPtr = headPtr->getNext();
        }
        else
        {
            // Find node that is before the one to remove
            Node<ItemType>* prevPtr = getNodeAt(position - 1);

            // Point to node to remove
            curPtr = prevPtr->getNext();

            // Disconnect indicated node from chain by connecting the
            // prior node with the one after
            prevPtr->setNext(curPtr->getNext());
        } // end if

        // Return node to system
        curPtr->setNext(nullptr);
        delete curPtr;
        curPtr = nullptr;
        itemCount--; // Decrease count of entries
    } // end if

    return ableToRemove;
} // end remove

In my main, I have following code:

const int ITEM_COUNT = 6;
    LinkedList<std::string>* list = new LinkedList<std::string>();
    list->insert(1, "Amy");
    list->insert(2, "Bob");
    list->insert(3, "Joe");


    for (int i = 0; i < ITEM_COUNT; i++) {
        std::cout << list->getEntry(i + 1) << '\n';
    }

    LinkedList<std::string>* list2 = new LinkedList<std::string>();
    *list2 = *list;

I was trying to check if my copy operator does right, but the error appears on the code: In template: no matching function for call to 'swap'

*list2 = *list;

Aucun commentaire:

Enregistrer un commentaire