Boost logo

Boost :

From: Eric Friedman (ebf_at_[hidden])
Date: 2003-02-18 20:30:47


Peter Dimov wrote:
> Eric Friedman wrote:
> >
> > In the past we sought to support the following...
> >
> > variant<...> var;
> > T* p = extract<T>(&var);
> > T& r = extract<T>(var);
> >
> > ...but it had to be dropped because (essentially) ambiguity exists
> > between the following:
> >
> > template <typename T, typename Extractable>
> > T& extract(Extractable & operand);
> > template <typename T, typename Extractable>
> > T* extract(Extractable * const operand);
>
> This is only ambiguous in its most general form given above. If you
rewrite
> it as
>
> template <class T, ...> T & extract(variant<...> & operand);
> template <class T, ...> T const & extract(variant<...> const & operand);
> template <class T, ...> T * extract(variant<...> * operand);
> template <class T, ...> T const * extract(variant<...> const * operand);
>
> it's no longer ambiguous.

I believe it is. The following (admittedly silly) example fails to compile
under Comeau:

// -- BEGIN CODE EXAMPLE --
template <class T, class Extractable> T & extract(Extractable & operand);
template <class T, class Extractable> T const & extract(Extractable const &
operand);

template <class T, class Extractable> T * extract(Extractable * operand);
template <class T, class Extractable> T const * extract(Extractable const *
operand);

int main()
{
  int i;
  extract<double>(i);
  extract<double>(&i); // error - ambiguous

  int* pi = &i;
  extract<double>(pi); // error - ambiguous
}
// -- END CODE EXAMPLE --

> The other option is to support a dynamic_cast-style extract:
>
> T * p = extract<T*>(&var);
> T & r = extract<T&>(var);
>
> but it would likely require partial ordering/specialization.

I've thought about this, but I think it would introduce significant
confusion among users.

For instance:

  variant<char, char*> v;
  char& c = extract<char&>(v); // ok... check for and either throw or
extract char
  char* c = extract<char*>(v); // check for and either return null or
extract: char? or char*?

Even though the statement is well-defined (extract char) under your proposed
syntax, I imagine many nonetheless would read the second line as extraction
of char* from v. (While in fact it would extract char from v.)

> "extract" is probably not the best name in both cases since it doesn't
> extract, it returns a reference to the internal representation.

I am open to suggestions on the name. I could not think of a better name
myself, nor am I certain that "access" (as others have proposed) is better.

> The documentation needs to describe when this reference is invalidated.

Thanks, noted.

Eric


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