2016-07-19 5 views
1

Я смущен, когда аргументы двоичной функции должны быть const T & или T &.О аргументах двоичной функции в C++

Может ли кто-нибудь сказать мне, почему sort(vec2.begin(), vec2.end(),cmp1());//error, why? ошибочен, а sort(vec1.begin(), vec1.end(),cmp2());//correct прав?

Все они имеют аргументы const T &.

Спасибо!

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? 
} 

ответ

1

Все они имеют const T & аргументы.

Это может сбивать с толку, но для cmp1 типа параметра (т.е. const Node *&) не const T&T==Node*), который должен быть Node* const&. Обратите внимание на разницу между указателем const (Node* const) и указателем на const (const Node*).

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

Тип элемента является Node*, которые не могут быть связаны с const Node* &. Поскольку Node* и const Node* - это не тот же тип, его необходимо преобразовать в const Node*, который будет временным и не может быть привязан к значению lvalue для не-const.

1

const Node* не const указатель. Это указатель на const Node. Это источник путаницы для многих.

Вы можете использовать:

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

или

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

Вместо мышления, что тип аргумента должен быть const T &, думаю, что это должно быть T const &. Тогда будет понятно, почему const Node* & - неправильный тип и почему Node* const & - правильный тип.

Смежные вопросы