C++ でいくつかの画像処理アルゴリズムを開発しています。コードをより一般化し、プロジェクト全体を再コンパイルせずにすべてを構成できるようにするために、処理アルゴリズムを小さな部分 (「エクストラクター」) に分割し、それらを単一のインターフェイスから継承されたオブジェクトとして作成し、ファクトリ メソッドによって解析された XML ファイルから実行順序とパラメータを構成します。しかし、これらの基本的な処理ブロックの入力と出力の型は異なる可能性があるため、一般化された型として boost::any を使用することを考えたので、画像を使用するすべての操作は次のようになります。
boost::any Process(const boost::any& feature);
すべてのオブジェクトは、適切な入力と出力の型を内部に格納し、実行するたびにボックス化とボックス化解除を実行する必要があります。そのようなテクニックを使うのは良い考えですか?それは私のニーズをある程度満たし、Pythonでは非常に自然ですが、同時にC++では醜いハックのように見えます。これは本質的に静的型付けであるため、使用する必要があるかどうかは疑問です。
UPD:より明確にするための小さな例
// Base class for all processing
template <typename Input, typename Output>
class Processor {
public:
virtual ~Processor();
virtual Output Process(const Input& input) const = 0;
};
// Generalized type-erased processor
typedef Processor<boost::any, boost::any> TypeErasedProcessor;
// Boxing-unboxing wrapper
template <typename Input, typename Output>
class ProcessorWrapper: public TypeErasedProcessor {
public:
boost::any Process(const boost::any& boxed_input) const {
Input input = boost::any_cast<Input>(boxed_input);
Output output = processor_->Process(input);
boost::any boxed_output = output;
return boxed_output;
}
private:
std::shared_ptr<Processor<Input, Output>> processor_;
};
class SimpleImageProcessingChain: public TypeErasedProcessor {
public:
boost::any Process(const boost::any& input) const {
boost::any result = input;
for (const auto& processor: processors_) {
result = processor->Process(result);
}
return result;
}
private:
std::vector<std::shared_ptr<TypeErasedProcessor>> processors_;
};