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 2

    Die 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!


  • Administrator

    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_OutputDimension nicht zur Kompilezeit bekannt ist, kannst du es nicht als zweiten Templateparameter an itk::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...


Anmelden zum Antworten