Reputation: 11037
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
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