[C++] Problem mit Templateüberladung

  • Themenstarter Themenstarter Gelöschtes Mitglied 16444
  • Beginndatum Beginndatum
G

Gelöschtes Mitglied 16444

Guest
Hi!

Ich habe eine Templateklasse Matrix, die verschiedene Matrixoperationen implementiert. Unter anderem auch das Bestimmen der adjungierten Matrix. Da sich die adjungierte für reele Matrizen anders bestimmen lässt, als für komplexe, benutze ich in der entsprechenden Methode der Matrixklasse eine global definierte Funktion, die der Benutzer dann für den von ihm verwendeten Typ selbst implementieren soll.
Zusätzlich stelle ich eine Standartimplementierung für die rudimentären PODs bereit. Diese habe ich als Templatefunktion implementiert und spezialisiere dieses Template über die boost Konstrukte enable_if und is_arithmetic soweit, dass es auch nur für diese Typen instantiiert werden kann.
Eine weitere Klasse leitet nun von einer konkreten Implementierung der Matrixklasse ab, sodass std::complex als Templateargument verwendet wird. Also muss ich hierfür eine eigene Implementierung meiner Hilfsfunktion bereitstellen und habe dafür die Templatefunktion für std::complex überschrieben.
Das ganze Konstrukt kompiliert unter VisualStudio 2008 einwandfrei. GCC 4.4.5 beschwert sich jedoch, dass keine für std::complex passende Funktion vorhanden sei. Grund hierfür ist wohl die Deklarationsreihenfolge. Die spezialisierte Funktion wird erst NACH dem Code deklariert, der sie aufruft. Normalerweise ein klarer Fall, aber der Compiler weiß doch erst bei der konkreten Verwendung der Matrixklasse, von welchem Typ das Templateargument ist und kann doch auch erst zu dem Zeitpunkt nach geeigneten Funktionen suchen, oder? Zu dem Zeitpunkt ist die überladende Funktion dann auch schon bekannt. Das ist dann vermutlich auch der Grund, warum es unter VC9 kompiliert?

Kann mir jemand sagen, welcher Compiler sich hier korrekt verhält?

Matrix.h
Code:
template<typename T>
typename boost::enable_if<boost::is_arithmetic<T>, T >::type
conjugate (const T & value) { return value; }

template<typename T>
class Matrix
{
public:

.
.
.

    const Matrix getAdjoint() const
    {
        Matrix result(this->m_columnCount, this->m_rowCount);

        for( size_t row=0; row<this->m_rowCount; ++row )
        {
            const std::vector<T> originalRow = (*this)[row];

            for( size_t column=0; column<this->m_columnCount; ++column)
            {
                result.SetElement( column, row, conjugate(originalRow[column]) );
            }
        }

        return result;
    }

.
.
.

};
ComplexMatrix.h
Code:
#include "Matrix.h"

inline const std::complex<double> conjugate (const std::complex<double> & value) { return conj(value); }

class ComplexMatrix: public Matrix< std::complex<double> >
{
.
.
.

void doStuff(); //hier wird getAdjoint() aufgerufen

.
.
.
};
 
Zurück
Oben