AMDG James Sutherland wrote:
I have had other occasions where I must do similar things and have addressed the issue through a mixture of polymorphism and class templates. For example:
class Base{ virtual void common_functionality(); };
template<typename T> class SpecialType : public Base { SpecialType( Patch& patch, FieldID id ) : patch_( patch ), id_( id ) { }
void common_functionality() { patch_.field_manager<T>().create_field( id_ ) } ... };
Now one can create something like:
typedef std::vector<Base*> mySet; mySet.push_back( new SpecialType<FieldType1>( patch, id1 ) ); mySet.push_back( new SpecialType<FieldType2>( patch, id2 ) ); ... for( std::vector<Base>::iterator i=mySet.begin(); i!=mySet.end(); ++i ) { i->common_functionality(); }
This hinges on being able to abstract all functionality into the common_functionality() method, however. Furthermore, it requires instantiation of a SpecialType object.
Is this a reasonable workaround, or one that makes generic-programming people cringe? :)
This is a perfectly reasonable approach. It works and it's the only method that I know of that works. The only issue I see is that it is not exception safe as written. If there is only a single operation, you can use Boost.Function. (Which uses a variation on the same theme internally) template<class T> struct SpecialType { SpecialType(FieldID id) : id_(id) {} void operator(Patch& patch) { patch.field_manager<T>().create_field( id_ ); } FieldID id_; }; std::vector<boost::function<void(Patch&)> > functions; function.push_back(SpecialType<FieldType1>(id)); In Christ, Steven Watanabe