2013-03-19 2 views
0

Я разрабатываю несколько алгоритмов обработки изображений в 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_; 
}; 
+0

'boost :: variant' лучше, если вы можете его использовать. – Pubby

+0

Я бы не стал лично; Я бы использовал иерархию «Image's» или что-то такое. –

ответ

2

В большинстве случаев, читаемость кода является более важным, чем возможность избежать перекомпиляции.

Если бы я работал с вашими алгоритмами, я определенно предпочел бы, чтобы они были статически напечатаны.

0

В этом случае нет. В этом случае вы действительно не сделали бы этого в Python; ваша функция в Python не может взять любой объект ; он будет работать только с объектами, которые реализуют конкретный протокол. Вы не будете работать на Python, если вы передаете его float или list из string; он будет работать только , если вы передадите ему что-то, что ведет себя как изображение, а имеет интерфейс изображения. Единственная разница между Python и C++ здесь заключается в том, что в C++, если объект реализует протокол , его необходимо объявить, наследуя от абстрактного базового класса , который определил интерфейс протокола.

+0

Это очевидно, я не пытаюсь заставить свою функцию работать с любым типом объекта, я объявляю типы ввода/вывода в XML и анализирую их во время выполнения вместо статической типизации. – lizarisk

Смежные вопросы