ファイルから読み取った C++ ツリー構造に格納されたデータがあります。ツリーは次のようになります。
class BaseNode {
std::vector<BaseNode*> children_;
...
};
class WhiteNode : public BaseNode { ... };
class BlackNode : public BaseNode { ... };
ツリーが構築された後、たとえば文字列に変換したいと思います。
ツリー コードを変換コードから分離しておくために、テンプレートを使用したいと思います。つまり、次のようなものを実装します。
template <class T>
T WhiteNode::Convert() { ... };
ただし、ツリー ノードは として格納されているため、BaseNode*
そのようなテンプレート メンバ関数にアクセスする方法がわかりません。また、テンプレートのメンバー関数は継承できないため、うまくいかないと思います。
ただし、実用的な解決策を思いつきました:
class BaseConversion {
public:
virtual ~BaseConversion() {}
virtual void * FromBlack() = 0;
virtual void * FromWhite() = 0;
};
template <class T>
class Conversion : public BaseConversion {
public:
void * FromBlack();
void * FromWhite();
};
class BaseNode {
std::vector<BaseNode*> children_;
virtual void * Convert(BaseConversion * conversion) = 0;
public:
virtual ~BaseNode() {}
template <class T>
T Convert() {
return *static_cast<T*>(Convert(new Conversion<T>));
}
};
class WhiteNode : public BaseNode {
void * Convert(BaseConversion * conversion) {
return conversion->FromWhite();
}
};
class BlackNode : public BaseNode {
void * Convert(BaseConversion * conversion) {
return conversion->FromBlack();
}
};
また、変換ロジックは完全に分離できます。
template <>
void * Conversion<std::string>::FromWhite() {
return new std::string("converting WHITE node to std::string ...");
}
template <>
void * Conversion<std::string>::FromBlack() {
return new std::string("converting BLACK node to std::string ...");
}
コードのテスト:
BaseNode * node = new BlackNode;
std::cout << node->Convert<std::string>() << std::endl;
node = new WhiteNode;
std::cout << node->Convert<std::string>() << std::endl;
期待される結果を返します:
converting BLACK node to std::string ...
converting WHITE node to std::string ...
このソリューションは機能しますが、はるかに簡単に実行できると確信しています。私が思いついた他のより単純な解決策は、たとえば型消去のために失敗しました。
それについて何か助けていただければ幸いです。ありがとう!