Compilerfehler discards qualifiers



  • C:\GroupRing\GroupRing\main.cpp|121|error: passing 'const GroupRingElement {aka const std::map<GroupElement, bool>}' as 'this' argument of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = GroupElement; _Tp = bool; _Compare = std::less<GroupElement>; _Alloc = std::allocator<std::pair<const GroupElement, bool> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = bool; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = GroupElement]' discards qualifiers [-fper|
    
    vector<GroupElement> G;
    
    typedef map<GroupElement,bool> GroupRingElement;
    
    GroupRingElement operator+ (const GroupRingElement& a, const GroupRingElement& b)
    {
        GroupRingElement result;
        for (auto g: G)
        {
            result[g] =  a[g] ^ b[g];
        }
        return result;
    }
    

    Wo liegt der Fehler?



  • Das sieht so aus als ob der Vergleichsoperator von GroupRingElement nicht const ist und daher nicht auf einem const Element aufgerufen werden darf.



  • Zeig mal was, falls vorhanden, den operator< von GroupElement.



  • class GroupElement
    {
        unsigned long long sigmaexp;
        unsigned long long tauexp;
    
    public:
        GroupElement() : sigmaexp(0), tauexp(0) {}
        GroupElement(unsigned long long a, unsigned long long b) : sigmaexp(a), tauexp(b) {}
    
        friend bool operator<(GroupElement a, GroupElement b)
        {
            if (a.sigmaexp < b.sigmaexp)
                return true;
            if (a.sigmaexp > b.sigmaexp)
                return false;
            return a.tauexp < b.tauexp;
        }
    
        friend bool operator==(GroupElement a, GroupElement b)
        {
            return ((a.sigmaexp == b.sigmaexp) && (a.tauexp == b.tauexp));
        }
    };
    


  • btw: operator^ ist bitweise, nicht logisch.



  • Ist doch etwas komplexer als ich dachte. Muss noch mal in Ruhe drüber schauen.


  • Mod

    TNA schrieb:

    Das sieht so aus als ob der Vergleichsoperator von GroupRingElement nicht const ist und daher nicht auf einem const Element aufgerufen werden darf.

    Das hat nichts mit dem Vergleichsoperator zu tun.

    Edit: Meine Erklärung war auch Unsinn.

    Edit²: Doch, meine Erklärung war völlig richtig:

    GroupRingElement hat keinen als const -qualifizierten operator[] .



  • maps haben keinen "[c]operator[] (..) const[/c]" da bei maps ja beim zugriff unter umständen etwas hinzugefügt werden kann. ergo musst du entweder mit map::at (c++11) oder mit map::find arbeiten.



  • Der Compiler ist offenbar der Meinung, dass a[g] und b[g] ein nicht const Element zurückgeben müssten, was bei einer const map natürlich nicht geht. Warum verstehe ich aber noch nicht.

    Edit: Mir war auch nicht klar, das maps keinen const operator [] haben. Damit sieht die Sache natürlich anders aus.



  • TNA schrieb:

    Der Compiler ist offenbar der Meinung, dass a[g] und b[g] ein nicht const Element zurückgeben müssten, was bei einer const map natürlich nicht geht. Warum verstehe ich aber noch nicht.

    also so wie ich die meldung interpretiere will uns der compiler sagen, dass a[g] und b[g] keine konstante methoden sind (und daher nicht aufgerufen werden können, da die maps per const& übergeben werden, dann können nämlich nur konstante methoden augerufen werden), damit hat er bei maps auch recht (siehe dazu meinen letzten post).



  • Jetzt kommt:

    GroupRingElement operator+ (const GroupRingElement& a, const GroupRingElement& b)
    {
        GroupRingElement result;
        for (auto g: G)
        {
            result[g] = a.at(g) ^^ b.at(g);
        }
        return result;
    }
    
    C:\GroupRing\GroupRing\main.cpp|121|error: expected primary-expression before '^' token|
    

  • Mod

    a.at(g) ^^ b.at(g)
    

    Soll das ein Scherz sein? Wenn du ein logisches XOR haben möchtest, nutze

    #define XOR(A, B) ( ((A) && !(B)) || (!(A) && (B)) )
    


  • fdgf schrieb:

    Jetzt kommt:

    GroupRingElement operator+ (const GroupRingElement& a, const GroupRingElement& b)
    {
        GroupRingElement result;
        for (auto g: G)
        {
            result[g] = a.at(g) ^^ b.at(g);
        }
        return result;
    }
    
    C:\GroupRing\GroupRing\main.cpp|121|error: expected primary-expression before '^' token|
    

    nein nein, was du willst ist vermutlich:

    GroupRingElement::const_iterator a_element = a.find(g), b_element = b.find(g);
    if(a_element == a.end() || b_element  == b.end()
    {
        // ...
    }
    result[g] = *a_element && !*b_element || !*a_element && *b_element;
    


  • Arcoth schrieb:

    a.at(g) ^^ b.at(g)
    

    Soll das ein Scherz sein? Wenn du ein logisches XOR haben möchtest, nutze

    #define XOR(A, B) ( ((A) && !(B)) || (!(A) && (B)) )
    

    schlechte idee.

    quizfrage: wie hoch sind a und b?

    #define XOR(A, B) ( ((A) && !(B)) || (!(A) && (B)) )
    int a = 0, b = 2;
    XOR(a++, --b);
    int f()
    {
        static int c = 0;
        return c++;
    }
    XOR(++b, f())
    

  • Mod

    Edit: Ahh, ich verstehe! Hast Recht.


  • Mod

    In dem Fall eine einfache Funktion

    bool XOR(bool lhs, bool rhs)
    {
        return char(lhs) + rhs == 1;
    }
    

    🤡



  • Arcoth schrieb:

    #define XOR(A, B) ( ((A) && !(B)) || (!(A) && (B)) )
    

    dann schon besser

    template<typename T> inline bool XOR(const T& A,const T& B){
    return ((A) && !(B)) || (!(A) && (B));
    }
    

    oder?


  • Mod

    Was soll das inline da? Und überhaupt, warum ein Template?



  • Arcoth schrieb:

    Was soll das inline da? Und überhaupt, warum ein Template?

    Stimmt ist hier unnötig. Wollte möglichst nah an das Macro kommen.



  • Arcoth schrieb:

    In dem Fall eine einfache Funktion

    bool XOR(bool lhs, bool rhs)
    {
        return char(lhs) + rhs == 1;
    }
    

    🤡

    ich habe gerade keinen standard zur hand aber ich glaube, es ist nicht definiert, dass char(true) == 1, lediglich dass char(true) != 0. :p


Log in to reply