8

Is it possible and why one would want to do it?

class Foo;
class Bar;

......

Foo foo;
Bar bar = static_cast<Bar>(foo);

Normally static_cast is used with numeric types and pointers, but can it work with user defined data types, a.k.a classes?

pic11
  • 14,267
  • 21
  • 83
  • 119
  • Yes, it can work, but you also have to know how to use it - here's a start on what each cast does in C++: http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used – wkl Sep 05 '11 at 21:10

2 Answers2

12
Bar bar = static_cast<Bar>(foo);

This cast will fail. Foo and Bar are incompatible types, unless atleast one of the following is true:

  • Foo is derived from Bar, Or
  • Bar has a constructor that takes Foo, Or
  • Foo has a user-defined conversion to Bar.

The bigger question here is not whether it will cast successfully or not. The bigger and the actual question should be: what do you want to get out of such cast? Why would you want to do such a thing in the first place? What is it supposed to do? I mean, how would the Bar object be initialized from Foo object?

The sensible way to convert one type to another is one of the following ways:

Either define Foo as:

class Foo : public Bar
{
   //...
};

Or define Bar as:

class Bar
{
  public: 
       Bar(const Foo &foo); //define this constructor in  Bar!
};

Or provide a conversion function in Foo as:

class Foo
{
  public: 
       operator Bar(); //provide a conversion function Foo to Bar!
};
Nawaz
  • 353,942
  • 115
  • 666
  • 851
11

Here's the rule:

The expression static_cast<T>(e) is valid if and only if the following variable definition is valid

T x(e);

where x is some invented variable.

So, in general, two unrelated types cannot be cast to one another. However, if one type is derived from the other, or when one defines a conversion function to the other, or has a constructor taking a single argument of the other type - in these cases static_cast will be well-defined.

Does it ever make sense? For example, if T defines a constructor that takes a single U and the constructor is explicit then static_cast<T>(e) where e is of type U would make perfect sense

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • 1
    It especially makes sense in generic code, for instance if T could be a user-defined type but also could be a built-in type. Then if you wrote `(T(e))` instead of `static_cast(e)` (extra parens to ensure it's not a definition of `e`), then that's a C-style cast equivalent to `((T)e)`, and for built-in types there's a risk of it turning into a `reinterpret_cast`. – Steve Jessop Sep 05 '11 at 23:34