Today, I encountered a compile issue in clang that surprised me. I guess is reasonable but I like to dig deeper and hear more details. Some standard references if possible also.
I have a class with a template method which rely on a member which his type is undefined in the header (but not in the source). Something like the following:
// Menu.h
class Page;
class Menu
{
public:
.... // stuff
template<class Visitor>
void VisitWidget( Visitor&& visitor);
private:
std::unique_ptr<Page> m_page; // destructor implemented in source file, so Page is an incomplete type
};
template<class Visitor>
inline void Menu::VisitWidget( Visitor&& visitor);
{
m_page->Visit( std::forward<Visitor>(visitor) );
}
In VisualStudio, it compiles. I expect this to only complain when instanciating; so inlining. However, in clang, this doesn't compile as soon as someone includes the header. Forcing me to include Page.h in Menu.h (which I want to avoid at all cost).
Like:
// Another.cpp (not Menu.cpp)
#include "Menu.h" // this trigger and error due Page is an incomplete type
even if the whole Another.cpp is not using VisitWidget (even in other headers)
I guess that this is caused by inline somehow, since the compiler is not obligated to really use it, but since there are templates in the middle I am not so sure. Is really clang checking the type?