Chris K
Chris K

Reputation: 12351

template specialization of a auto_ptr<T>

Maybe I'm overcomplicating things, but then again, I do sort of like clean interfaces. Let's say I want a specialization of auto_ptr for an fstream - I want a default fstream for the generic case, but allow a replacement pointer?

 template <> 
 class auto_ptr<fstream> {
     static fstream myfStream; 
     fstream* ptr; 

 public: 
     auto_ptr() { 
         // set ptr to &myfStream;
     }
     reset(fstream* newPtr) {
         // free old ptr if not the static one. 
         ptr = newPtr 
     };
  } 

Would you consider something different or more elegant? And how would you keep something like the above from propagating outside this particular compilation unit?

[The actual template is a boost::scoped_ptr.]

EDIT:

It's a contrived example. Ignore the fstream - it's about providing a default instance of object for an auto_ptr. I may not want to provide a specialized instance, but would like to keep the auto_ptr semantics for this static default object.

class UserClass { 
public:
    auto_ptr<fstream> ptr; 
    UserClass() {  }
} 

I may not provide an dynamic object at construction time - I still want it to have a meaningful default. Since I'm not looking at ownership-transfer semantics, it really shouldn't matter that my pointer class is pointing to a statically allocated object, no?

Upvotes: 3

Views: 483

Answers (3)

Potatoswatter
Potatoswatter

Reputation: 137850

You might get something that compiles and works, but I wouldn't do that if I were you.

Boost defines certain functionality for the construction of an auto_ptr. If you redefine that somehow, you have violated their specification.

Invent a name for your new functionality, make it a factory function, and don't worry about specializing someone else's template.

EDIT: deriving from auto_ptr is another option, if you're really set on changing initialization semantics:

tempate < class T, T *d > 
struct defaulted_auto_ptr
    : public auto_ptr< T > {
    defaulted_auto_ptr( T *p = d ) throw() : auto_ptr<T>( p ) {} // set default
    defaulted_auto_ptr( auto_ptr<T> &r ) throw()
        : auto_ptr<T>( r ) {} // allow conversion
    template< class O > defaulted_auto_ptr( auto_ptr<O> &r ) throw()
        : auto_ptr<T>( r ) {}
};

fstream default_file;
typedef defaulted_auto_ptr< fstream, &default_file > file_ptr;

auto_ptr< fstream > baseptr = file_ptr(); // can assign to auto_ptr, but unsafe

I'm a little doubtful of the cost-benefit tradeoff of this, but it's better than entirely reimplementing auto_ptr.

You still have to figure out what to do if a defaulted object is destroyed. default_file above will be deleted, potentially many times.

Upvotes: 1

user283145
user283145

Reputation:

This wouldn't end up good. The biggest problem is that std::auto_ptr deletes the underlying object in its destructor. This means your default parameter can't be static. The only choice you can make is to do a lot of hacks there and IMHO the price you'll pay while maintaining all that crappy code isn't worth the small advantage you'd have.

Upvotes: 2

James
James

Reputation: 25533

That looks reasonable to me, could be confusing if it's use is widespread in a codebase and not documented though.

I notice you are being carful, but I'm going to stress it anyway: make sure you don't double-free your static object!

Upvotes: 1

Related Questions