B has not been declared
-
Hallo,
folgendes Minimalbeispiel welches mein Problem reflektiert. Ich gebe alle Dateien an und verstehe nicht warum der compiler mit der Meldung "B has not been declared" schreibt obwohl ich die Klasse B verfügbar mache. Wichtig: Impl.h ist keine Klasse sondern bietet nur die deklaration/definition von bar() an:
main.cpp
#include <iostream> #include "A.h" int main(int argc, int** argv) { int b = 8; A<double> a = A<double>(b); }A.h
#include "Impl.h" #ifdef INCLUDE_A #define INCLUDE_A template <class T> class A { public: A<T>(int b) { bar<T>(b); }; ~A<T>() { }; }; #endifImpl.h
#include "B.h" template<class T> inline void bar(int b, B b) { // std::cout << b << std::endl; }B.h
#ifdef INCLUDE_B #define INCLUDE_B template <class T> class B { public: B() { }; ~B() { }; }; #endif
-
Wie wärs mit
#ifndef INCLUDE_A //und #ifndef INCLUDE_B //anstatt #ifdef INCLUDE_A //und #ifdef INCLUDE_B
-
eh...das ändert leider nix
-
#include "B.h" template<class T> inline void bar(int b, B b) //2 x ein Formalparameter b, und B ist ein Template... { // std::cout << b << std::endl; }
-
Mehrere kleine Fehler, ich fange mal hinten an:
B.h#ifdef INCLUDE_B #define INCLUDE_B template <class T> class B { public: B() { }; ~B() { }; }; #endifSoweit ok.
Impl.h
#include "B.h" template<class T> inline void bar(int b, B b) // Hier verwendest du 2x den Bezeichner b, was nicht erlaubt ist. Außerdem bezeichnet B alleine keinen Typ, du musst das template spezialisieren, also sowas wie B<T>. { // std::cout << b << std::endl; } // hier fehlt ein ;A.h
#include "Impl.h" #ifdef INCLUDE_A #define INCLUDE_A template <class T> class A { public: A<T>(int b) // das <T> ist unnötig { bar<T>(b); // Der Konstruktor von bar ist oben anders deklariert. Er nimmt genau zwei Argumente. }; ~A<T>() { }; // hier ist das <T> ebenfalls unnötig }; #endifmain.cpp
#include <iostream> #include "A.h" int main(int argc, int** argv) { int b = 8; A<double> a = A<double>(b); }Wenn du die Änderungen umsetzt, geht's.
-
eh doch sorry...
-
ich danke euch für eure Hilfe. Leider funktioniert es bei meinem normalen code nicht obwohl es hier im minimalbeispiel funktioniert. Kann es sein dass die Kompilierreihenfolge eine Rolle spielt? Könnte es dass wenn B.h erst irgendwie nach Impl.h kompiliert wird bzw. nach A.h dass es dann nicht geht?
-
SeppJ schrieb:
Mehrere kleine Fehler, ich fange mal hinten an:
#include "B.h" template<class T> inline void bar(int b, B b) // ... { // std::cout << b << std::endl; } // hier fehlt ein ; MIT SICHERHEIT NICHT!Das Semikolon ist nicht nach dem "}" nötig (Das gilt auch für die Methoden im Header, die eine Implementierung direkt enthalten (Bei der reinen Methoden/Funktionsdeklaration ist es nötig).
Zudem sehe ich sehr viele Fehler in dem Originalcode, werde zeitlich aber nicht darauf eingehen.
-
Ok - nochmal von vorn. Ich hoffe jetzt das Minimalbeispiel so zu haben wie bei meinem großen code:
- Die main.cpp liegt im obersten Ordner
#include <iostream> #include "A.h" int main(int argc, int** argv) { int b = 8; A<double> a = A<double>(b); }Impl.h liegt im Unterordner variante/Impl.h. Also da wo z.B. main.cpp liegt
ist noch ein Ordner variante in dem jetzt Impl.h liegt:#include "../B.h" inline void bar(int b) { // std::cout << b << std::endl; }Dann die A.h die wieder neben der main.cpp liegt.
#include "Impl_Env.h" #include "B.h" #ifndef INCLUDE_A #define INCLUDE_A template <class T> class A { public: A<T>(int b); ~A<T>() { }; }; #include "A.imp" #endifUnd die A.imp die ebenfalls neben der A.h liegt:
template<class T> A<T>::A(int b) { bar(b); };Und die B.h die neben der A.h liegt:
#ifndef INCLUDE_B #define INCLUDE_B template <class T> class B { public: B() { }; ~B() { }; }; #endifUnd schießlich die Impl_Env.h die ebenfalls neben der main.cpp liegt. Sie ist dafür verantwortlich dass auch variante/Impl.h eingebunden wird. Natürlich ist hier nur ein Zweig vorhanden - also immer mit -DFLAG kompilieren.
#ifdef FLAG #include "variante/Impl.h" #endifIch bekomme folgende Fehlermeldung von meinem gcc compiler:
A.imp:4: error: there are no arguments to ‘bar’ that depend on a template parameter, so a declaration of ‘bar’ must be availableDas ist mir nicht klar weil bar eigentlich vorhanden ist.