Headereinbindungen bei templates
-
Headless schrieb:
Nexus schrieb:
Das stimmt nicht. Bei der Verwendung von Templates muss ihre Definition sichtbar sein (damit der Compiler die Instanziierung durchführen kann), doch Deklarationen sind nach wie vor möglich, wo ein unvollständiger Typ erlaubt ist.
Wie genau meinst du das?
#include <iostream> struct Foo; template<typename T> void useFooBar(const T& value) { Foo foo; foo.bar(value); } struct Foo { void bar(int value) { std::cout << "bar " << value << std::endl; } }; int main() { useFooBar(42); }Wäre useFooBar kein Template, sondern eine normale Funktion, müsste bereits bei der Definition von useFooBar die Funktion Foo::bar bekannt sein. In diesem Fall reicht es aber, wenn Foo::bar in main bekannt ist, da erst hier das Template instanziert wird.
-
-
Und bei falls der Typ unvollständig sein darf, reicht eine Vorwärtsdeklaration.
template <typename T> class Template; Template<int>* pointer;
-
Ok! Das macht Sinn. Bei mir ist die Struktur, aber um eingies komplexer, wodurch nicht erst in der main instanziiert wird:
Base.h
#pragma once class Helper; class upperBase { public: virtual void use()=0; }; template<class T> class Base : public upperBase { public: virtual void use() { Helper::bar<Concrete>(); } };Concrete.h
#pragma once #include "Base.h" class Concrete : public Base<int> { public: Concrete(); };Concrete.cpp
#include "stdafx.h" #include "Concrete.h" Concrete::Concrete() { }Helper.h
#pragma once static class Helper { public: template<class P> static P bar() { P p; return p; } };Folgende Fehler entstehen:
error C2027: Verwendung des undefinierten Typs "Helper"
error C2065: 'bar': nichtdeklarierter Bezeichner
error C2275: 'Concrete': Ungültige Verwendung dieses Typs als AusdruckIn die Base.h "#include "Helper.h" " einzufügen ist leider keine Lösung...auch wenn das in diesem Beispiel funktioniert...
-
- #pragma once ist Compilerabhängig, verwende lieber das übliche #ifdef zeugs.
- Eine static class existiert in C++ nicht.
-
Dann schreib halt
virtual void use(); //ohne Implementierungund in einen anderen Header, den du dann inkludierst
#include "Base.h" #include "Concrete.h" #include "Helper.h" template<typename T> void Base<T>::use() { Helper::bar<Concrete>(); }
-
Aber das ist doch auch nur von hinten in die Brust geschossen...
Wenn ich " #include "Helper.h" " in einem Header benutze, den ich dann wiederum inkludiere, dann kann ich die Helper.h auch direkt inkludieren?!
@314159265358979:
2) Mein Compiler beschwert sich aber gar nicht bei der static class?!
-
Headless schrieb:
- Mein Compiler beschwert sich aber gar nicht bei der static class?!
Bist du sicher? Wie auch immer, Compiler dürfen Erweiterungen anbieten. Willst du portables C++ programmieren, verzichte auf
static class.
-
Das ist seltsam, welchen Compiler hast du?
-
Da ist nichts in den Kopf geschossen. Nochmal:
BaseDeclarations.h//hier includeguards!! class upperBase { public: virtual void use()=0; }; template<class T> class Base : public upperBase { public: virtual void use(); };Concrete.h
//hier includeguards!! #include "BaseDeclarations.h" class Concrete : public Base<int> { public: Concrete(); };Helper.h
//hier includeguards!! class Helper { public: template<class P> static P bar() { P p; return p; } };Base.h
//hier includeguards!! #include "Base.h" #include "Concrete.h" #include "Helper.h" template<typename T> void Base<T>::use() { Helper::bar<Concrete>(); }