2016-07-19 5 views
1

Ich bin verwirrt, wenn die Argumente der binären Funktion const T & oder T & sein sollten.Über die Argumente der binären Funktion in C++

Könnte mir jemand sagen, warum sort(vec2.begin(), vec2.end(),cmp1());//error, why? falsch ist, während sort(vec1.begin(), vec1.end(),cmp2());//correct richtig ist?

Sie alle haben const T & Argumente.

Danke!

struct Node{ 
    Node(char ch, int num):ch_(ch), num_(num){ pnext_ = nullptr, pprev_ = nullptr; } 
    char ch_; 
    int num_; 
    Node *pnext_; 
    Node *pprev_; 
    // bool operator < (const Node &no) const { return num_ > no.num_; }//最小值优先 
    // bool operator > (const Node &no) const { return num_ < no.num_; }//最大值优先 
}; 
struct cmp0{ 
    bool operator() (Node * &p1, Node * &p2) const 
    { 
     return p1->num_ > p2->num_; 
    } 
}; 
struct cmp1{ 
    bool operator()(const Node * &p1, const Node * &p2) const 
    { 
     return p1->num_ > p2->num_; 
    } 
}; 
struct cmp2{ 
    bool operator()(const Node &p1, const Node &p2) const 
    { 
     return p1.num_ > p2.num_; 
    } 
}; 
struct cmp3{ 
    bool operator()(Node &p1, Node &p2) const 
    { 
     return p1.num_ > p2.num_; 
    } 
}; 
int main(int argc, char *argv[]) 
{ 
    vector<Node> vec1; 
    vector<Node*> vec2; 
    sort(vec1.begin(), vec1.end(),cmp2());//correct 
    sort(vec1.begin(), vec1.end(), cmp3());//correct 
    sort(vec2.begin(), vec2.end(), cmp0());//correct 
    sort(vec2.begin(), vec2.end(),cmp1());//error, why? 
} 

Antwort

1

Sie alle haben const T & Argumente.

Es kann verwirrend sein, aber für cmp1 der Parametertyp (d.h. const Node *&) nicht const T& (mit T==Node*), die Node* const& sein sollte. Beachten Sie den Unterschied zwischen dem Zeiger const (Node* const) und dem Zeiger auf const (const Node*).

sort(vec2.begin(), vec2.end(),cmp1());//error, why?

Der Elementtyp ist Node*, die nicht zu const Node* & gebunden werden konnte. Da und const Node* nicht vom selben Typ sind, muss er in const Node* konvertiert werden, was ein temporärer Wert ist und nicht an den Lvalue-Verweis auf non-const gebunden werden kann.

1

const Node* ist kein const Zeiger. Es ist ein Zeiger auf eine const Node. Dies ist eine Quelle der Verwirrung für viele.

können Sie verwenden:

struct cmp1{ 
    bool operator()(Node* p1, Node* p2) const 
    { 
     return p1->num_ > p2->num_; 
    } 
}; 

oder

struct cmp1{ 
    bool operator()(Node* const & p1, Node* const & p2) const 
    { 
     return p1->num_ > p2->num_; 
    } 
}; 

Statt des Denkens, die das Argument Typ const T &, denken sein muss, dass es T const & sein muss. Dann macht es Sinn, warum const Node* & nicht der richtige Typ ist und warum Node* const & der richtige Typ ist.