Cannot appear in a constant expression
-
Hallo
Bin gerade ein bisschen am Verzweifeln. Muss auch dazu sagen, dass ich relativ neu in der OOP bin.
Warum geht im Konstruktor Folgendes:
const unsigned int dimension = 4; typedef itk::Image< TimeStepExtractorFilter::ImagePixelType, dimension > OutputImageType;aber Folgendes nicht:
const unsigned int dimension = m_OutputDimension; typedef itk::Image< TimeStepExtractorFilter::ImagePixelType, dimension > OutputImageType;Der Compiler bringt mir dann immer folgenden Fehler:
In file included from /home/erik/workspace/ITKSeries/timeStepExtractorFilter.h:57,
from /home/erik/workspace/ITKSeries/main.cxx:9:
/home/erik/workspace/ITKSeries/timeStepExtractorFilter.txx: In constructor ‘TimeStepExtractorFilter<TImage>::TimeStepExtractorFilter()’:
/home/erik/workspace/ITKSeries/timeStepExtractorFilter.txx:23: error: ‘dimension’ cannot appear in a constant-expression
/home/erik/workspace/ITKSeries/timeStepExtractorFilter.txx:23: error: template argument 2 is invalid
/home/erik/workspace/ITKSeries/timeStepExtractorFilter.txx:23: error: invalid type in declaration before ‘;’ token
make[2]: *** [CMakeFiles/ITKSeries.dir/main.o] Error 1
make[1]: *** [CMakeFiles/ITKSeries.dir/all] Error 2
make: *** [all] Error 2Die Headerdatei:
#ifndef TIMESTEPEXTRACTORFILTER_H_ #define TIMESTEPEXTRACTORFILTER_H_ #include "itkImage.h" #include "timeStepExtractorFilter.h" template< class TImage> class TimeStepExtractorFilter { public: TimeStepExtractorFilter(); //virtual ~timeStepExtractorFilter(); typedef TimeStepExtractorFilter Self; typedef TImage InputImageType; typedef typename InputImageType::Pointer ImagePointer; typedef typename InputImageType::RegionType ImageRegionType; typedef typename InputImageType::SizeType ImageSizeType; typedef typename InputImageType::IndexType ImageIndexType; typedef typename InputImageType::PixelType ImagePixelType; void Start( void ); //setter methods void SetSliceNumber( unsigned int ); void SetInputImage( ImagePointer ); //getter methods unsigned int GetSliceNumber( void ); private: unsigned int m_sliceNumber; unsigned int m_InputDimension; unsigned int m_OutputDimension; ImagePointer m_InputImage; ImageRegionType m_InputRegion; }; #include "timeStepExtractorFilter.txx" #endif /* TIMESTEPEXTRACTORFILTER_H_ */Ich muss den typedef doch im Konstruktor machen, wenn die dazu benötigte Variable m_OutputDimension erst da ermittelt werden kann. Und m_OutoutDimension muss ich ja schon in der Headerdatei deklarieren. Allerdings kann ich das nicht mit const machen.
Ich steh grad irgendwie aufm Schlauch. Kann mir vielleicht einer helfen?Danke euch!
-
Die Werte von Template-Parametern müssen zur Compiezeit feststehen. bei dimension = 4 ist das der Fall, bei dimension = m_OutputDimension nicht, wenn das keine Compilezeitkonstante ist.
-
Danke für die Antwort.
Ok, verstanden.
Gibt es eine Möglichkeit, dass ich den Typ(also die Dimension) variabel festlegen kann, weil diese ja erst zur Laufzeit bekannt ist.
Also die Membervariable m_OutoutDimension frag ich erst im Konstruktor ab, und diese ist wiederrum von TImage abhängig.Vielen Dank!
-
Erikly schrieb:
Gibt es eine Möglichkeit, dass ich den Typ(also die Dimension) variabel festlegen kann, weil diese ja erst zur Laufzeit bekannt ist.
Mit Templates nicht.
Was du aber tun kannst, ist dynamische Speicherverwaltung, zum Beispiel mit STL-Containern. Dann übergibst du die Grösse nicht als Template-, sondern als Konstruktorparameter.
-
Hallo!
Ich nochmal.
Ähm so richtig weiß ich ehrlich gesagt nicht, was gemeint ist.
Ich würde auch ungern Konstruktorparameter verwenden.
Kann man das Problem vielleicht sogar über Makros lösen, oder lieg ich da falsch?
Wäre cool, wenn mir einer eine kleine Hilfestellung geben könnte.
Grüße, Erik!
-
Erikly schrieb:
Wäre cool, wenn mir einer eine kleine Hilfestellung geben könnte.
Und wie? Wir haben keine Informationen, mit welchen wir dir helfen könnten. Wir können nur sagen, dass man keine variable Werte als Templateparameter übergeben kann. Solange der Wert von
m_OutputDimensionnicht zur Kompilezeit bekannt ist, kannst du es nicht als zweiten Templateparameter anitk::Imageübergeben.Grüssli
PS: Du kennst die Standardbibliothek mit den Standardcontainer aber schon? Also du werkelst da nicht mit Templates rum, bevor du die C++ Bibliothek kennen gelernt hast?
-
Erikly schrieb:
...Ähm so richtig weiß ich ehrlich gesagt nicht, was gemeint ist....
Hi,
ich vermute, Dein Problem hat nicht wirklich was mit templates zu tun, sondern mit der Verwendung des template-Parameters "dimension".
Die sehen wir aber nicht (vllt. bin ich nur blind ?) und so können wir hier nur raten.Mein erster Lottotipp:
Du hast sowas wie// in der Deklaration irgendeinTyp var_name[dimension]; // ... irgendwo initialisieren. for(i=0; i<dimension; ++i) var_name[i] = irgendeinWert;Dann wäre ein guter Ansatz
// in der Deklaration std::vector<irgendeinTyp> var_name; // ... irgendwo initialisieren. for(i=0; i<dimension; ++i) var_name.push_back(irgendeinWert); // ...oder var_name.resize(dimension); for(i=0; i<dimension; ++i) var_name[i] = irgendeinWert;Vorteil: Bei der Konstruktion Deines umgebenden Objektes muss die dimension noch gar nicht unbedingt feststehen, sondern Du kannst sie nach Belieben zu Lebnzeiten des Objekts ändern.
Was hast Du eigentlich gegen Ctor-Parameter?
Gruß,
Simon2.
-
Erikly schrieb:
Ähm so richtig weiß ich ehrlich gesagt nicht, was gemeint ist.
Immer noch das Gleiche: Dass die Variablen, die als Template-Argumente eingesetzt werden, konstante Ausdrücke sind, also zur Compilezeit bekannte Werte haben müssen.
Erikly schrieb:
Ich würde auch ungern Konstruktorparameter verwenden.
Warum das?
Erikly schrieb:
Kann man das Problem vielleicht sogar über Makros lösen, oder lieg ich da falsch?
Makros bringen da nichts, eher noch weniger, da sie sogar noch vor dem Kompilieren aufgelöst werden.
Erikly schrieb:
Wäre cool, wenn mir einer eine kleine Hilfestellung geben könnte.
Wie gesagt wäre die STL eine Methode, mehrere Objekte dynamisch zu verwalten. Wenn du C++ effizient lernen willst, solltest du dich vielleicht einmal damit beschäftigen. Simon2 hat in seinem Post auch einiges erklärt...