template methode mit typename?



  • Hallo zusammen,

    ich habe eine utility class mit statischen Methoden,
    bei denen eine Methode wie folgt aussieht:

    class UtilCellUserPointer
    {
        template <int dim>
        static element::Element<dim>  & getRefToCellElement(const typename dealii::DoFHandler<dim>::active_cell_iterator  & cell);
    
    }
    

    Sie wird an anderer Stelle wie folgt aufgerufen:

    const Material<dim> cellMaterial = UtilCellUserPointer::getRefToCellElement(cell).getMaterial();
    

    Dabei wird vom Compiler folgende Fehlermeldung ausgegeben:

    source/internal/solver_unit.cpp(980): error: no instance of function template "ares::utilities::UtilCellUserPointer::getRefToCellElement" matches the argument list
    argument types are: (const dealii::TriaActiveIterator<dealii::DoFCellAccessor<dealii::DoFHandler<2, 2>>>)
    const Material<dim> cellMaterial = UtilCellUserPointer::getRefToCellElement(cell).getMaterial(); // get the material of the cell
    ^
    detected during instantiation of "dealii::FullMatrix<double> ares::internal::SolverUnit<dim>::computeCellMatrix(const dealii::DoFHandler<dim, dim>::active_cell_iterator &, const dealii::FEValues<dim, dim> &) const [with dim=2]" at line 720

    Ich vermute, dass das irgendwas mit dem typename zu tun hat, denn die anderen Funktionen funzen alle, weiss es aber nicht genau...

    Ich bin für jede neue Idee dankbar...

    Rahul



  • Rahul0891 schrieb:

    template <int dim>
    Element<dim> & getRefToCellElement(const typename DoFHandler<dim>::active_cell_iterator & cell);
    

    Sie wird an anderer Stelle wie folgt aufgerufen:

    getRefToCellElement(cell)
    

    "typename DoFHandler<dim>::active_cell_iterator" ist ein sogenannter "non-deducible context" bzgl des Template-Parameters "dim". Und weil das der einzige Kontext ist, bei dem "dim" auftaucht, kann "dim" nicht automatisch bestimmt werden. Du musst entweder den Parameter explizit beim Aufruf angeben, oder Dein Funktionstemplate umschreiben, zB so:

    template<class Iter>
    Element<...>& getRefToCellElement(Iter cell);
    

    Leider fehlen Informationen über dein restliches Programm, dass ich für "..." hier nichts einsetzen kann. Du kannst Dich aber mal mit std::iterator_traits vertraut machen und/oder eine eigene "Metafunktion" schreiben, die Dir die richtige Dimension zurückgibt.



  • Ah, jetzt hats *ding* gemacht 🙂

    Ansonsten, wenn die Funktion selbst nicht umgeschrieben werden kann/soll, kann man den Aufruf umschreiben:
    (wobei das natürlich die weniger schöne Lösung ist)

    // const Material<dim> cellMaterial = UtilCellUserPointer::getRefToCellElement(cell).getMaterial();
    // ->
    const Material<dim> cellMaterial = UtilCellUserPointer::getRefToCellElement<dim>(cell).getMaterial();
    


  • Super, danke für die Antworten...

    Nach ein wenig Recherche war ich auch in der Lage,
    aus dem Iterator, der mir von einer Library so vorgegeben war,
    die Information über dim auf einfache Weise zu extrahieren...

    So sieht es dann aus:

    class UtilCellUserPointer
    {
        template <typename IteratorType>
        static element::Element<IteratorType::AccessorType::dim>  & getRefToCellElement(const IteratorType  & cell);
    }
    

    Alles Gute und nochmals danke
    Rahul


Anmelden zum Antworten