How can the presence of an ofstream data member of a base class prevent the casting to a subclass? If I leave the ofstream data member in Person, GCC 4.8.1 complains that the static_cast is ambiguous. With Microsoft Visual C++ 2012, it compiles fine if the ofstream data member remains in Person.
class Person {
private:
std::string name;
//std::ofstream personFile; // With this in, the program won't compile because it considers the static_cast ambiguous
};
class Girl: public Person {};
class Cheerleader: public Girl {
private:
int cheeringSkill;
public:
Cheerleader () {}
Cheerleader (const Girl&); // constructor to allow conversion of Girl to type Cheerleader
};
Cheerleader::Cheerleader (const Girl& girl) {}
int main () {
Girl Mary;
std::cout << typeid (Mary).name() << std::endl;
Cheerleader _Mary = static_cast<Cheerleader> (Mary);
std::cout << typeid (_Mary).name() << std::endl; // type cast successful
return 0;
}
#include <typeinfo> was in my code, I just didn't paste any of the #includes here. But did this compile when you allowed the ofstream data member to be in Person, i.e. uncommented 'std::ofstream personFile;'?
According to SneakySnake (5), it actually is not supposed to compile in that case. In that case, the bug is not in GCC but in Microsoft Visual C++ for allowing it to be compiled when it shouldn't.
Thanks JLBorges for finding the solution to the problem. Your solution works, but I had to remove the line
Person( Person&& that ) noexcept = default ;
(my Person class is actually an abstract class due to its many pure virtual functions, and I think that might be the reason why this line won't compile. Update: I ran a test, and Person being abstract is not the reason why the above line won't compile, but some other reason I have yet to find). error: function 'Person::Person(Person&&)' defaulted on its first declaration with an exception-specification that differs from the implicit declaration 'Person::Person(Person&&)'
Is that line really necessary? I haven't studied references to rvalue expressions yet, but will today. I ran my program and it so far has no problems without that line. Incidentally, the Person copy constructor is never being called, even though that was needed to solve the problem.
> error: function 'Person::Person(Person&&)' defaulted on its first declaration
> with an exception-specification that differs from the implicit declaration
'Person::Person(Person&&)'
> Yes, mea culpa. std::ifstream is not no-throw-move-constructible.
Ah. Now the line compiles, so now Person is moveable as a bonus. You guessed correctly that Person has ifstream data members too. Thank you so much. You are also the first person to answer my first post in this forum when I was a total beginner a few months ago.