Boost logo

Boost :

From: Brian McNamara (lorgon_at_[hidden])
Date: 2003-08-31 22:29:12


On Sun, Aug 31, 2003 at 09:12:59PM -0600, Dave Gomboc wrote:
> > The point is that optional<T> is not a T, and most notably, a template
> > function will never perform the coercion. Replace the lines like
> > B b = get<2>(args);
> > in your example with real calls to, e.g.
> > do_something( get<2>(args) )
> > and do_something() is likely to fail if it's a template function
> > (expecting a T and not an optional<T>).
>
> Okay, you've demonstrated that it may not be possible to drop-in
> optional<T> for T with zero code changes when T is not a scalar type.
> (Usually, my Ts are! ;-) Nonetheless, it is at least still possible to
> write generic code that accepts either T or the wrapped T, which is
> definitely an improvement over writing a whack of special-casing code.

Indeed.

[snipped most of code]

> template <typename T>
> class nilable {
> public:
...
> operator T(void) const {
> if (nil_) throw std::bad_cast();
> return value_;
> };
...

I'd add

      T get() { return T(*this); }
      // in reality, return T& -- using T here just to show the idea

...
> try {
> nilable< std::vector<int> > nv(v);
> //output(nv); // true, this fails
> output(std::vector<int>(nv)); // but this succeeds!
          
As does

          output( nv.get() );

> nilable< std::vector<int> > nv2;
> output(std::vector<int>(nv2)); // and this throws as expected.

Again I'd prefer

          output( nv2.get() );

I was originally arguing with Joel because I thought he wanted to use
exactly "nv" and not anything like "nv.get()". I think now that we've
cleared up the confusion about get() returning a reference instead of a
pointer, we're all back on the same page.

-- 
-Brian McNamara (lorgon_at_[hidden])

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk