1

これは私が使用しようとしている提供された関数テンプレートです:

template <class Process, class BTNode>
void postorder(Process f, BTNode* node_ptr)
{
   if (node_ptr != 0)
   {
      postorder( f, node_ptr->left() );
      postorder( f, node_ptr->right() );
      f( node_ptr->data() );
   }
}

これは私の呼び出しであり、私が渡している関数です:

void city_db::print_bst() {
   postorder(&city_db::print, head);
}

void city_db::print(city_record target)
{
   std::cout << target.get_code();
}

これは、コンパイル時 (G++) エラーです。

CityDb.cpp:85: ここからインスタンス化

BinTree.template:80: エラー: ' を使用する必要があります。' または '-> ' 'f (...)' でメンバーへのポインタ関数を呼び出す</p>

make: *** [CityDb.o] エラー 1

これはf( node_ptr->data() );、関数テンプレートの行を参照しています。

これはデータ構造プロジェクト用です。関数に関数を渡す必要がないように割り当てが変更されましたが、私はかなり前からこれに興味があり、ほとんどここにあるような気がします。私は Google とラボの TA を使い果たしたので、StackOverflow にアイデアがあれば大歓迎です。

4

4 に答える 4

7

あなたの問題は、 postorder がこの方法で呼び出さなければならない関数オブジェクトを受け入れることです:

f(arg);

メンバー関数へのポインターを渡しています。最初に mem_fun を呼び出して、ポインターからメンバーへの関数オブジェクトを作成する必要があります。

std::mem_fun(&city_db::print)

返された関数オブジェクトは、city_db へのポインター (暗黙的な this ポインター) と出力されるオブジェクトの 2 つの引数を取ります。次のように、bind1st を使用して最初のものをこれにバインドできます。

std::bind1st(std::mem_fun(&city_db::print), this)

これで postorder を呼び出すことができるはずです:

postorder(std::bind1st(std::mem_fun(&city_db::print), this), head);
于 2009-12-04T21:01:44.807 に答える
3

city_db呼び出すには のインスタンスが必要ですprint

渡しているのはメンバー関数へのポインター (vtable のスロットと考えてください) ですが、thisポインターも必要です。これを別の引数として関数に渡すことができpostorderます。

template <class Object, class Process, class BTNode>
void postorder(Object* obj, Process f, BTNode* node_ptr)
{
   if (node_ptr != 0)
   {
      postorder(obj, f, node_ptr->left() );
      postorder(obj, f, node_ptr->right() );
      ((obj)->*(f))( node_ptr->data() );
   }
}

C++ FAQ Liteを参照してください

于 2009-12-04T20:54:17.460 に答える
0

city_db::print() を静的にするか、city _db オブジェクトを提供する必要があります。

于 2009-12-04T21:04:30.660 に答える
0

書かれている通り

void city_db::print(city_record target)
{
   std::cout << target.get_code();
}

クラスの状態に依存しません。静的関数として宣言すると、コンパイラはthisそれを呼び出すためのポインターを必要としません。 トピックに関するよくある質問。

于 2009-12-04T21:08:05.663 に答える