Search code examples
c++c++11structconstructordefault-constructor

The default constructor cannot be referenced


I am making a school project and I need to create a library system with bidirectional list and structures. I want to implement constructors to make my code more clear. The problem shows up when i want to creacte struct for bidirectional list and reserve memory space for list element using new list_of_books. The error msg I am getting is no matching function call to Book::Book() and the default constructor of "list_of_books" cannot be referenced -- it is deleted function. What does it mean and how can I fix that?

struct User {
  std::string name;
  std::string surname;
  User(std::string name, std::string surname) 
    : name(name), surname(surname) {}
};

struct Date {
  int day;
  int month;
  int year;
  Date(int day, int month, int year) 
    : day(day), month(month), year(year) {}
};

struct Book {
  int id;
  std::string title;
  struct User author;
  std::string cathegory;
  struct Date hire_date;
  struct User reader;
  std::string others;
  Book(int id, std::string title, std::string nameA, std::string surnameA, std::string cathegory, int day, int month, int year, std::string nameR, std::string surnameR, std::string others) 
    : id(id), title(title), author(nameA, surnameA), cathegory(cathegory), hire_date(day, month, year), reader(nameR, surnameR), others(others) {}
};

struct list_of_books {
  struct Book book;
  list_of_books* next;
  list_of_books* prev;
};

void push(Book data) {
  if (head == NULL) {
    list_of_books* element = new list_of_books;
    element->book = data;
    element->prev = NULL;
    element->next = NULL;
    head = element;
  } else {
    list_of_books* curr = head;

    while(curr->next != NULL) {
      curr = curr->next;
    }

    list_of_books* element = new list_of_books;
    element->book = data;
    element->prev = curr;
    element->next = NULL;
    curr->next = element;
  }
}

Solution

  • struct User {
      std::string name;
      std::string surname;
      User(std::string name, std::string surname) 
        : name(name), surname(surname) {}
    };
    

    this constructor is harmful. You have an aggregate -- a type that is its data -- and a constructor that just repeats the members in order.

    Do this:

    struct User {
      std::string name;
      std::string surname;
    };
    

    and repeat for every other constructor you wrote.

    Constructors that do nothing but repeat the arguments in order are not good things.

    If you remove every constructor in your program, your program will compile.


    Now what is going wrong? By creating a constructor, you delete the default no-argument constructor.

    Then when you new list_of_books, it tries to use the constructor for Book, which doesn't exist.


    Note that when working with aggregates, you have to use {} brace construction lists if you want to construct them in place, like Book b = {"The Bookiest Book", "Bob Smith"};, instead of () for the arguments.