2012-07-25 1 views
0

포인터의 벡터를 사용하여 힙의 일련의 노드 객체를 확보하고 있습니다. 벡터에는 모든 노드 객체 주소가 있으며 for_each 루프와 함께 벡터의 모든 노드를 삭제하는 데 사용되는 delete_nodes 함수가 있습니다. 어떤 이유로 나는의 for_each 루프와 이클립스 CDT에 다음과 같은 오류가 빨간색 밑줄이 얻을 :for_each 호출은 포인터 벡터와 작동하지 않습니다.

error: no matching function for call to 'for_each(__gnu_cxx::__normal_iterator<Node**, std::vector<Node*, std::allocator<Node*> > >, __gnu_cxx::__normal_iterator<Node**, std::vector<Node*, std::allocator<Node*> > >, <unresolved overloaded function type>)' 

코드는 허프만 코딩, 그리고의 for_each 루프는 맨 끝에 있습니다. nodes_delete 벡터는 while 루프 바로 전에 만들어집니다.

void Huff::delete_nodes(Node*n){//this is used to delete all the nodes in the binary tree at the end of Huff::compress() 
    delete n; 
} 
vector<Code>* Huff::compress(){ 
    //-------GETTING WEIGHTS/FREQUENCIES------ 
    vector<Node *>* nodes = new vector<Node*>; // Vector of nodes for later use 
    map<char, int>* freq = new map<char, int>; // Map to find weight of nodes 
    for(unsigned int i = 0; i < content.length(); i++) 
     (*freq)[content[i]]++; 
    CopyTo copyto(nodes); //sets vector<Node*> to copy to 
    for_each(freq->begin(), freq->end(), copyto); // Copies 
    delete freq; 
    vector<Node *>::iterator beg = nodes->begin(); 

    //-------SETTING UP TO BUILD TREE------ 
    if(nodes->size() % 2 == 1){ //makes sure there are an even number of nodes 
     Node* fill = new Node; 
     fill->set_node(0, '*', NULL, NULL); 
     nodes->push_back(fill); 
    } 
    huff_sort(nodes); // sort nodes by weight 
    vector<Node*> nodes_delete(*nodes); //this is used to delete all the nodes in the binary tree at the end 
    //-------BUILDING TREE------ 
    while(nodes->size() != 1){ //Sorts nodes by weight and then removes two of them and replaces them with one 
     int w= (**beg).weight + (**(beg+1)).weight; 
     Node* p = new Node; 
     p->set_node(w, '*', *nodes->begin(), *(nodes->begin()+1)); //making it the parent node of the two lowest nodes 
     nodes->erase(nodes->begin(), nodes->begin()+2); 
     unsigned int i = 0; 
     while(w > (*nodes)[i]->weight && i <= nodes->size()){ //finds where to insert the parent node based on weight 
      i++; 
     } 
     if(i > nodes->size()) //if it needs to be inserted at the end 
      nodes->push_back(p); 
     else 
      nodes->insert(nodes->begin()+i, p); 
    } 
    //-------TRAVERSING TREE------ 
    Node* root = (*nodes)[0]; 
    delete nodes; 
    vector<Code>* codes = new vector<Code>; 
    traverse(root, codes , ""); 
    delete root; 
    for_each(nodes_delete.begin(), nodes_delete.end(), delete_nodes); 
    return codes; 
} 
+0

'delete_nodes' 함수에 대해 하나 이상의 (과부하 된) 정의가 있습니까? 위의 코드에서 하나만 볼 수 있지만 헤더 파일 중 하나에 다른 파일이 있는지 여부를 확인 했습니까? – jogojapan

+0

@jogojapan 내가 아는 한 다른 delete_nodes가 없습니다. 또한 delete_nodes의 이름을 다른 것으로 변경하면 오류가 계속 발생합니다. –

+0

Btw 나는'delete_nodes' 함수가 정적 멤버 함수로 정의되어 있다고 가정했습니다. 실제로 맞습니까? 그렇지 않다면 아래의 Matteo Italia가 맞습니다 (비록 컴파일러가 오해의 소지가있는 오류 메시지를 발견 할지라도). – jogojapan

답변

3

delete_nodes은 비 정적 멤버 함수입니다. 그렇다면 을 std::for_each의 인수로 사용할 수 없습니다. std::for_each에는 펑터가 필요합니다. delete_nodes은 Functor가 아닙니다.

첫째, 비 정적 멤버 함수에 대한 포인터를 얻으려면 & 연산자와 정규화 된 이름이 항상 필요합니다. 비 정적 멤버 함수 (단순한 delete_nodes)의 단순한 이름은 C++에서 유효한 표현식이 아닙니다. &Huff::delete_nodes을해야합니다.

두 번째로 멤버 함수에 대한 포인터 ("일반"함수에 대한 포인터와 반대)는 다시 한 번 functor가 아닙니다. Functor로 바꾸려면 std::mem_fun 함수를 사용할 수 있습니다. std::mem_fun은 암시적인 this 매개 변수를 명시 적 매개 변수로 바꿔주기 때문에 바이너리 펑터를 제공합니다. std::for_each이 요구하는 단항 functor로 변환하려면 첫 번째 인수를 특정 객체 포인터 값 (this?)으로 바인드해야합니다. 이 this 개체에 대한 delete_nodes를 호출하는 단항 펑터이다

bind1st(mem_fun(&Huff::delete_nodes), this) 

위의 단계의 최종 결과는 볼 것이다. 구현 delete_nodes정적 멤버 함수로 전환 할 수있다처럼 그러나

for_each(nodes_delete.begin(), nodes_delete.end(), 
    bind1st(mem_fun(&Huff::delete_nodes), this)); 

을 다음과 같이

따라서, 귀하의 예제에서 for_each 호출이 보일 것입니다, 그것은 보인다. 정적 멤버 함수는 "일반적인"함수입니다. 즉, 함수가 functor이며 직접 사용될 수 있음을 의미합니다. 나는. delete_nodes을 정적으로 만들면 코드가 그대로 작동해야합니다.

따라야 할 경로를 결정하고 필요한 사항을 변경하십시오.

3

제한없는 멤버 함수를 functor로 전달하려고합니다. 예를 들어를 사용하여 현재 객체에 바인딩해야합니다. std::mem_fnbind.