Sometimes it can be an annoyance that c++ defaults to allow slicing. For example
struct foo { int a; };
struct bar : foo { int b; };
int main() {
bar x{1,2
I'm not sure if there is a named idiom for it but you can add a deleted function to the overload set that is a better match then the base classes slicing operations. If you change foo
to
struct foo
{
int a;
foo() = default; // you have to add this because of the template constructor
template
foo(const T&) = delete; // error trying to copy anything but a foo
template
foo& operator=(const T&) = delete; // error assigning anything else but a foo
};
then you can only ever copy construct or copy assign a foo
to foo
. Any other type will pick the function template and you'll get an error about using a deleted function. This does mean that your class, and the classes that use it can no longer be an aggregate though. Since the members that are added are templates, they are not considered copy constructors or copy assignment operators so you'll get the default copy and move constructors and assignment operators.