Why can I not instantiate a class whose constructor is private in a friend class?

You need Employee's ctor to call the ctor of Salary. The ctor of Salary is not accessible from main.

eg:

class Employee {
public:
    Employee() : sal() {}
    public:
        std::string name_;
        Salary sal;
};

If you erase the "{}" after "Employee emp" in your main() function it compiles just fine (gcc 7.3.1 on Fedora 27).


Because you don't provide a constructor for Employee the braces in your initialization Employee emp{}; will perform an aggregate initialization, which essentially means that each member is initialized one-by-one using the default rules, in the context of main(). Since main() doesn't have access to the Salary constructor, it fails.

As others have pointed out, adding an Employee default constructor will resolve your problem:

class Employee {
    public:
        Employee() = default;
        std::string name_;
        Salary sal;
};