0

ポインタのベクトルを使用して、ヒープ内の一連のノードオブジェクトを解放しています。ベクターにはすべてのノードオブジェクトアドレスがあり、関数delete_nodesがあります。この関数は、ベクター内のすべてのノードを削除するためにfor_eachループで使用されます。何らかの理由で、for_eachループに赤で下線が引かれたEclipsecdtで次のエラーが発生します。

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ループは最後にあります。ノード_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;
}
4

2 に答える 2

3

ファンクターとして無制限のメンバー関数を渡そうとしています。たとえば、 std :: mem_fnを使用して現在のオブジェクトにバインドし、バインドする必要があります

于 2012-07-25T02:00:09.557 に答える
3

あなたdelete_nodesは非静的メンバー関数のようです。delete_nodesその場合、の引数として使用することはできませんstd::for_eachstd::for_eachファンクターが必要です。あなたdelete_nodesは関手ではありません。

まず、非静的メンバー関数へのポインターを取得するには、&演算子と修飾名が常に必要です。非静的メンバー関数の単なる名前(ちょうどdelete_nodes)は、C++では有効な式ではありません。あなたはしなければなりません&Huff::delete_nodes

第二に、ここでも、(「通常の」関数へのポインターではなく)メンバー関数へのポインターはファンクターではありません。それをファンクターに変えるために、あなたはstd::mem_fun関数を使うことができます。これにより、暗黙のパラメーターが明示的なパラメーターに変わるため、バイナリファンクターが得られます。それを必要な単項ファンクターに変換するには、最初の引数を特定のオブジェクトポインター値(おそらく?)にバインドする必要があります。std::mem_funthisstd::for_eachthis

上記の手順の最終結果は次のようになります。

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

delete_nodesこれは、thisオブジェクトを呼び出す単項ファンクターです。

したがって、for_each例の呼び出しは次のようになります。

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

ただし、実装では静的メンバー関数delete_nodesに変換できるようです。静的メンバー関数は「通常の」関数です。つまり、ファンクターであり、直接使用できます。つまり、静的にすると、コードはそのまま機能するはずです。delete_nodes

たどるパスを決定し、必要な変更を加えます。

于 2012-07-25T02:02:46.593 に答える