user2023370
user2023370

Reputation: 11037

Cast to reference to base class with no additional data members?

Is it safe to static_cast a concrete base class object, to a reference to a derived concrete class object when the derived class has no additional data members? Here is a simple example for illustration:

#include <array>

struct Foo : std::array<int,3>
{
  Foo() : std::array<int,3>{1,2,3} {}

  void hello() { std::cout << "Hello\n"; }
};

Foo test()
{
  std::array<int,3> a{4,5,6};
  return static_cast<Foo&>(a);
}

Upvotes: 0

Views: 366

Answers (1)

Chris Dodd
Chris Dodd

Reputation: 126263

As others have noted, this is undefined behavior (so unsafe) even though it is likely to work for POD types with no virtual members or bases. It's easy enough to do it safely by just defining the appropriate constructor:

#include <array>

struct Foo : std::array<int,3>
{
  Foo() : std::array<int,3>({1,2,3}) {}

  void hello() { std::cout << "Hello\n"; }

  Foo(const std::array<int, 3> &a) : std::array<int,3>(a) {}
};

Foo test()
{
  std::array<int,3> a{4,5,6};
  return a;
}

and then no cast is actually needed.


If for some bizarre social reason (assignment requirements?) you're not allowed to change the definition of Foo, you can get around this by using an adaptor class:

struct Foo : std::array<int,3>
{
  Foo() : std::array<int,3>({1,2,3}) {}

  void hello() { std::cout << "Hello\n"; }
};

struct FooAdaptor : public Foo {
  FooAdaptor(const std::array<int, 3> &a) {
    *this = a;
  }
};

Foo test()
{
  std::array<int,3> a{4,5,6};
  return FooAdaptor(a);
}

but I would not recommend this for real code

Upvotes: 1

Related Questions