Topic: Explicit should apply to conversion operators


Author: phalpern@truffle.ultranet.com (Pablo Halpern)
Date: 1996/02/22
Raw View
clamage@Eng.Sun.COM (Steve Clamage) wrote:

>Whether "explicit" should also apply to type conversion operators
>has been discussed here and in the C++ committee. Some people on
>the committee thought that the proposal to add "explicit" for
>constructors also applied to conversion operators, but the
>proposal did not contain that wording.
>
>Personally, I don't see much utility in "explicit" for conversion
>operators. If you don't want a type conversion to be implicit, don't
>use a conversion operator, use a named function instead. Example:
> [ example deleted ]
>You don't have this option with constructors, and the workarounds for
>the lack of "explicit" constructors are often ugly.
>
>The only advantage I can see for an "explicit" conversion operator is
>that a name for a complicated type, especially one involving pointers
>or references, might be inconvenient and not intuitive. In that
>case you might prefer to be able to cast to char**& instead of thinking
>up a name for that type.

I used to believe this, also, but two things changed my mind:

The first is templates. When creating a template function or class, one
might want to specify that a class used for template instantiation has
the requirement that it be explicitly convertable to, say, int or char*
or String. For example:

  LinkList<string> traceLog;

  template <class T>
  Trace(const T& t) { traceLog.append(static_cast<string> t); }

  class X { ... explicit operator string() const; ... }
  X x;
  Trace(x);
  string y;
  Trace y;

This would not work if the only way to convert from an X to a string was
to call and as_string() function, since not all types that are
convertable to String would have an as_string() function, expecially not
class string itself!  This goes double for built-in types, where we
don't have the option of adding class members.

The second, slightly less significant reason is to provide a little bit
more syntactic sugar when building types that work like the built-in
ones.  For example:

  // Complex number class
  class Complex
  {
    Complex(double);  // implicit conversion from double
    Complex(double, double);
    as_double() const;  // explicit conversion to double
    explicit operator double() const;  // perferred conversion notation
    ...
  };

  f1(Complex);
  f1(4.5);  // Ok, implicit conversion
  f2(double);
  Complex c(1.2, 3.4);
  f2(c);    // Error: no implicit conversion to double
  f2(c.as_double());  // OK, but doesn't work like built-in types
  f2(double(c));      // explicit conversion, works like built-in types

The above would work if we didn't declare the conversion operator
explicit, but then we could have accidental loss of information if a
complex number were passed into a function requiring a double. The use
of an explicit cast makes it clear that the programmer knows what she/he
is doing, and it uses a normal cast syntax.

Given the existance of the "explicit" keyword, wouldn't it be a
reasonable addition to make it work for conversion operators as well as
for constructors?

-------------------------------------------------------------
Pablo Halpern                   phalpern@truffle.ultranet.com

I am self-employed. Therefore, my opinions *do* represent
those of my employer.
---
[ To submit articles: Try just posting with your newsreader.  If that fails,
                      use mailto:std-c++@ncar.ucar.edu
  FAQ:    http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
  Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]