Angus Leeming <[EMAIL PROTECTED]> writes: | Attached is a simple sample showing how I could use boost::any to implement | the transformation stuff in InsetExternal.
I do not agree with how you use operatesOn. | template<typename Factory, typename Data> | TransformCommand::ptr_type | getTransformer(Data const & data) const { | TransformCommand::ptr_type ptr; | | if (operatesOn(data)) { | Factory factory = boost::any_cast<Factory>(value); | ptr = factory(data); | } | | return ptr; | } IMHO you should do the try/catch right there in getTransformer, no need to do the any_cast twice. template<typename Factory, typename Data> TransformCommand::ptr_type getTransformer(Data const & data) const { TransformCommand::ptr_type ptr; try { Factory factor = boost::any_cast<Factory>(value); ptr = factory(data); } catch (boost::bad_any_cast const &) { } return ptr; } Of course this functions really should just throw if wrong factory is used, and not return a empty ptr in that case: template<typename Factory, typename Data> TransformCommand::ptr_type getTransformer(Data const & data) const { TransformCommand::ptr_type ptr; Factory factor = boost::any_cast<Factory>(value); return factory(data); } And the caller should handle the try and catch. (getTransformer could catch the exception, but should rethrow it (as another type perhaps). | I think it results in very elegant code, but the killer is the try,catch | block. The block is needed, so I guess that this means I cannot use the | appropach within lyx? If we all agree that we want to use exceptions, I am all for it. But that is up to the rest of you. | // This loop is all that needs go in insetexternal.C | int main() | { | std::vector<TransformStore> factories; | build(factories); > | RotationData rotationdata(30); | ResizeData resizedata(2); > | string command = "\\input{foo}"; > | std::vector<TransformStore>::const_iterator it = factories.begin(); | std::vector<TransformStore>::const_iterator end = factories.end(); | for (; it != end; ++it) { | TransformCommand::ptr_type ptr; | ptr = it->getTransformer<RotationFactory>(rotationdata); | if (!ptr.get()) | ptr = it->getTransformer<ResizeFactory>(resizedata); | | if (ptr.get() == 0) | continue; > | std::ostringstream os; | os << ptr->front() << command << ptr->back(); | command = os.str(); | } > | std::cout << command << std::endl; | } for (; it != end; ++it) { TransformCommand::ptr_type ptr; try { ptr = it->getTransformer<RotationFactory>(rotationdata); } catch (...) { try { ptr = it->getTransformer<ResizeFactory>(resizedata); } catch (...) { continue; } } std::ostringstream os; os << ptr->front() << command << ptr->back(); command = os.str(); } But I would rewrite a bit further to make it even simpler... -- Lgb