Heute stieß ich auf ein Kompilierproblem beim Klang, das mich überraschte. Ich denke, es ist vernünftig, aber ich mag es, tiefer zu graben und mehr Details zu hören. Einige Standardreferenzen wenn möglich auch.Warum wird ein unvollständiger Typ innerhalb einer Template-Methode erkannt?
Ich habe eine Klasse mit einer Template-Methode, die auf einem Mitglied, dessen Typ ist nicht definiert in der Kopfzeile (aber nicht in der Quelle). So etwas wie das Folgende:
// 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 kompiliert es. Ich erwarte, dass sich dies nur beim Instanciating beschweren wird; so inlining. In clang wird dies jedoch nicht kompiliert, sobald jemand den Header hinzufügt. Erzwingt, dass ich Page.h in Menu.h einfüge (was ich um jeden Preis vermeiden möchte).
Like:
// Another.cpp (not Menu.cpp)
#include "Menu.h" // this trigger and error due Page is an incomplete type
, auch wenn die ganze Another.cpp nicht VisitWidget (auch in anderen Header) mit
Ich denke, dass dies irgendwie durch Inline verursacht wird, da der Compiler nicht verpflichtet ist, um es wirklich zu benutzen, aber da es Templates in der Mitte gibt bin ich mir nicht so sicher. Klingt wirklich der Typ?
@chris, siehe meine Antwort. Es ist ein bekannter Fehler in MSVC. – SergeyA