私はC++でテンプレート構造のバイナリ検索ツリーを開発しています。今まではすべてがうまくいっています。この問題は、私が慣れ親しんでいない、ぎこちないC++のものを扱っています。私は助けが必要です。C++関数ポインタのキャスト
これまで、ツリーを走査し、各ノードを異なる順序で訪問する関数を定義しました。ここで問題となるのは以下のように定義される。
TreeNode.h
public:
static void PostOrderVisit(TreeNode<T>* node, void visit(const T& v));
TreeNode.cpp
template <class T> void TreeNode<T>::PostOrderVisit(TreeNode* node, void visit(const T& v)) {
if (node->leftChild != NULL)
PostOrderVisit(node->leftChild, visit);
if (node->rightChild != NULL)
PostOrderVisit(node->rightChild, visit);
visit(node->value);
}
これは、ノードを作成し、静的PostOrderVisitを呼び出すテストプログラムで正常に動作します。
フレンドクラス(BinSTree.h/cpp)では、ツリー内のすべてのノードを削除するメソッドを実装していますので、この訪問者を使用してDelete()関数を呼び出すことをお勧めします。各ノード(Delete()関数もBinSTreeのテストプログラムで正常に機能します)。
この関数は、以下のように定義されています。
template <class T> void BinSTree<T>::ClearTree() {
TreeNode<T>::PostOrderVisit(this->root(), &BinSTree<T>::Delete);
}
ここに問題があります。 ...この場合、
BinSTree.cpp:156: error: no matching function for call to ‘TreeNode<int>::PostOrderVisit(TreeNode<int>*, void (BinSTree<int>::*)(const int&))’
TreeNode.cpp:56: note: candidates are: static void TreeNode<T>::PostOrderVisit(TreeNode<T>*, void (*)(const T&)) [with T = int]
を言う++ gが、私はvoid (BinSTree<T>::*)(const T&)
がvoid (*)(const T&)
のインスタンスだろうと思ったが、そうではありません。私は、呼び出しは関数定義によって認識されるように得ることができる唯一の方法は、このような関数ポインタをキャストすることによって、次のとおりです。
TreeNode<T>::PostOrderVisit(this->root(), (void (*)(const T& v)) &BinSTree<T>::Delete);
これは、関数を認識し、適切にそれを呼び出します(ただし、これにはいくつかの重要な研究をしました... )、C++のメンバ関数には暗黙的なパラメータがあり、 'this'キーワードを内部からアクセスすることができます。メンバ関数ポインタをプレーン関数ポインタにキャストすると 'this'参照が完全に削除され、Delete()メソッドがsegフォルト(これはかなり 'これ'を使用します)の原因になります。
これは面倒なことであり、私はこのプロジェクトのこのような小さな部分にかなりの時間を費やしてきました。誰でも私に、A:キャスティングなしで機能を認識させる方法、B:キャスト全体で 'this'リファレンスを維持する方法を教えてください。 ClearTree()メソッドとDelete()メソッドは、どちらも同じクラス内にあります。
ありがとうございます。
すでにテンプレートを使用している場合は、関数ポインタをスキップしてファンクタに直接アクセスしてください。非仮想関数ポインタでないポインタをインライン化することができます。 'visit'を' operator()() 'を多重定義できるテンプレートにします。 – asveikau