Reputation: 13
I am beginning a basic implementation of a template LinkedList class. When I compile the header file alone with g++ there is not problem. However, when I try to compile with another class that implements a certain type of the linked list, it gives me an error. It seems to want to compile an object of the type of the node. Why would it do so? The Node constructor doesn't call the constructor of the template type.
I will post all the relevant header files. There may be extraneous code, but I wanted to show what is being used. I will post the error message followed by the linked list implementation, then the class that uses the linked list, and then the ParkingLot constructor that is mentioned in error.
Here is the error message:
LinkedList.h: In instantiation of ‘Node<T>::Node(T) [with T = ParkingLot]’:
LinkedList.h:46:9: required from ‘void LinkedList<Type>::addNode(Type) [with Type = ParkingLot]’
Decal.h:20:28: required from here
LinkedList.h:13:16: error: no matching function for call to ‘ParkingLot::ParkingLot()’
Node(T input) {
^
LinkedList.h:13:16: note: candidates are:
In file included from Decal.h:2:0,
from test.cpp:3:
ParkingLot.h:28:2: note: ParkingLot::ParkingLot(int, std::string, int, int, int, int)
ParkingLot(int num_spaces, std::string name, int x, int y, int randSpacesPercent, int randLotPercent){
^
ParkingLot.h:28:2: note: candidate expects 6 arguments, 0 provided
ParkingLot.h:7:7: note: ParkingLot::ParkingLot(const ParkingLot&)
class ParkingLot {
^
ParkingLot.h:7:7: note: candidate expects 1 argument, 0 provided
ParkingLot.h:7:7: note: ParkingLot::ParkingLot(ParkingLot&&)
ParkingLot.h:7:7: note: candidate expects 1 argument, 0 provided
Could anyone provide some advice? I have no idea why it would try to construct a ParkingLot object when I only want to construct a Node of type ParkingLot.
Here is the implementation:
#include <iostream>
template <typename T> class Node {
public:
/*Class variables*/
T data;
Node* next;
/*Class constructors*/
Node(T input) {
data = input;
next = NULL;
}
};
template <typename Type> class LinkedList {
public:
/*Class variables*/
Node<Type>* head;
/*Class constructor*/
LinkedList(){
head = NULL;
}
/*Class Methods*/
void addNode(Type value) {
Node<Type>* p;
if (head == NULL) {
head = new Node<Type>(value); ********ERROR
}
else {
p = head;
while (p->next != NULL){
p = p->next;
}
p->next = new Node<Type>(value); ************ERROR
}
}
//Check to see if linked list contains specified value
bool contains(Type value) {
Node<Type>* search;
if ( head != NULL) {
search = head;
}
else {
return false;
}
while(search->next != NULL) {
if (search->data.compare(value)) {
return true;
}
search = search->next;
}
if (search->next == NULL && search->data.compare(value)) {
return true;
}
else {
return false;
}
}
void print(){
Node<Type>* p;
p = head;
while (p != NULL) {
std::cout << p->data.print() << " ";
p = p->next;
}
std::cout << "\n";
}
};
Here is the code from the Decal class which just tries to use a linked list of type parking lot. It is designed in this way so that some amount of parking lots correspond to a type of decal.
#include <string>
#include "ParkingLot.h"
#include "LinkedList.h"
class Decal {
//Class Variables
private:
LinkedList <ParkingLot> decal_list;
std::string decal_name;
//Class Methods
public:
Decal(std::string name) {
decal_name = name;
}
void addLot(ParkingLot newLot) {
decal_list.addNode(newLot);
}
bool hasLot(ParkingLot searchLot) {
return decal_list.contains(searchLot);
}
};
Lastly, I have included the Parking Lot constructor for reference. It has a name and locations x,y as well as other parameters for filling its spaces.
ParkingLot(int num_spaces, std::string name, int x, int y, int randSpacesPercent, int randLotPercent){
//Generate bool array for parking spaces
lot_capacity = num_spaces;
for (int i =0; i<lot_capacity; i++) {
parking_lot[i] = true;
}
/*Determine if lot is full or not, and if not generate random full spaces*/
//Assigning percentages to corresponding variable
sp_generator = randSpacesPercent;
lot_generator = randLotPercent;
//Make lot full or not based on percentage
generateLot(lot_generator);
//If lot is not full, assign certain percentage of spots as full/empty
if (isFull() == false) {
generateSpaces(sp_generator);
}
//Assing other vars
parking_lot_name = name;
x_locat = x;
y_locat = y;
}
Thank you for any help you can provide!
Upvotes: 1
Views: 631
Reputation: 172984
The ctor of Node
called the default ctor of type T
, and then assign it in the body of ctor. If type T
does not have a default ctor, compile will fail.
It's better to use initializer list in constructor instead of assignment, it will call the copy ctor of type T
. And it can improve the performance in most cases.
Node(T input) : data(input), next(NULL) {}
BTW: It's better to use const reference for the parameter input
, it can avoid once copy.
Node(const T& input) : data(input), next(NULL) {}
Upvotes: 1