0

I am so confused. I have a nested class where Book is the inner and Bookshelf is the outer class. When I try to create a Book object in my Bookshelf class like Book b; it will work IF i have an empty constructor in my Book class. But when I try to use my current Book constructor that takes in 3 values, I cant declare it in my Bookshelf class. Why is that?

This is the error Im getting:

d.cpp:48:17: error: expected identifier before string constant
   48 |         Book b ("Hello", "2", 12);
      |                 ^~~~~~~
d.cpp:48:17: error: expected ',' or '...' before string constant 

This is my code:

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <stdexcept>

using namespace std;

class Bookshelf
{
public:
Bookshelf() = default;
 class Book
    {
    private:
            string title {};
            string author {};
            int pages {};
            int readers {};
        
        public:
            Book(string const& t, string const& a, int const p)
                : title{t}, author{a}, pages{p}, readers{0}
            {
            }

            string get_title () const
            {
                return title;
            }

            void print() const
            {
                cout << "Title: " << title << "\nAuthor: " << author
                     << "\nPages: " << pages << "\nReaders: " << readers << endl;
            }


        };

    void add_book(Book const& b) 
    {
    bookshelf.push_back(b);
    }

    private:
        vector<Book> bookshelf {};
        Book b ("Hello", "2", 12);
};

int main()
{
    Bookshelf::Book book_1("Hej", "Me", 100);
    Bookshelf::Book book_2("Yo", "Me", 150);
    Bookshelf bookshelf_1;

    return 0;
}
  • 2
    In-class initializer cannot use `()`, you must use `Book b {"Hello", "2", 12};` or `Book b = Book("Hello", "2", 12);`. This has nothing to do with nested classes btw, any initialization with `()` would fail, e.g. `std::string bookshelfName ("default name");` would also fail. – Yksisarvinen May 14 '22 at 23:57
  • @Yksisarvinen ohhh is there a reason why thats the case? – Programming Newbie May 15 '22 at 00:00
  • because creating an object outside the class would have to use () if the members are private and theres a constructor. however u apparently have to use {} when u are in a class. its that just how it is or is there a reason – Programming Newbie May 15 '22 at 00:01
  • 1
    There is a reason. The notation is a new addition to the language, and care was taken so it would not conflict with the prior notation (as the code is trying to do with `b` member variable), since that already had syntactical and semantic meaning. Obligatory [The Nightmare of Initialization in C++](https://www.youtube.com/watch?v=7DTlWPgX6zs) by Nicolai Josuttis. An hour long presentation on the initialization syntax pain point in C++. – Eljay May 15 '22 at 00:04
  • See the linked duplicates (at the top of the page). The short answer is "because otherwise it could be ambiguous whether you mean a function or an object". Also, *outside the class would have to use ()* is not true. Using `{}` is called *uniform initialization* for a reason and is generally recommended everywhere unless you cannot use it (e.g. in the situation where class provides a constructor with `std::initailizer_list`, but you need to call another one). – Yksisarvinen May 15 '22 at 00:08

0 Answers0