5

現在、C++ でバイナリ ツリーを実装しており、in_order() という関数を使用してトラバースしたいと考えています。

関数を引数として渡す方法はありますか?

struct tree_node; // and so on
class  tree;      // and so on

void print_node () {
  // some stuff here
}

// some other functions

tree mytree();

// insert some nodes

mytree.in_order(print_node);
mytree.in_order(push_node_to_stack);
mytree.in_order(something_else);
4

3 に答える 3

15

はい、これはさまざまな方法で実行できます。ここに2つの一般的な可能性があります。

古いスタイルの関数ポインタ

class mytree
{
    // typedef for a function pointer to act
    typedef void (*node_fn_ptr)(tree_node&);

    void in_order(node_fn_ptr)
    {
        tree_node* pNode;

        while (/* ... */)
        {
        // traverse...
        // ... lots of code

        // found node!
            (*fnptr)(*pNode);
            // equivalently: fnptr(*pNode)
        }
    }
};

void MyFunc(tree_node& tn)
{
    // ...
}

void sample(mytree& tree)
{
    // called with a default constructed function:
    tree.inorder(&MyFunc);
    // equivalently: tree.inorder(MyFunc);
}

ファンクターの使用

テンプレートメンバーを使用して、関数ポインターを操作します

class mytree
{
    // typedef for a function pointer to act
    typedef void (*node_fn_ptr)(tree_node&);

    template<class F>
    void in_order(F f)
    {
        tree_node* pNode;

        while (/* ... */)
        {
        // traverse...
        // ... lots of code

        // found node!
            f(*pNode);
        }
    }
};

struct ExampleFunctor
{
    void operator()(tree_node& node)
    {
        // do something with node
    }
}

void sample(mytree& tree)
{
    // called with a default constructed function:
    tree.inorder(ExampleFunctor());
}
于 2009-11-04T12:01:33.580 に答える
2

はい、へのパラメータとして関数ポインタを使用できますin_order。渡された関数のシグネチャが一致しない場合に備えて、オーバーロードする必要がある場合もあります。のような関数の場合print_node、次のようにin_orderを宣言します(戻り型voidも同様である場合)。

void tree::in_order( void (*)() )
{
   //implementation
}
于 2009-11-04T12:03:16.287 に答える