Say I have this structure:
struct F
{
int& ref; // reference member
const int c; // const member
// F::F() is implicitly defined as deleted
};
That is from cppreference. As I understand from the documentation the constructor of F
is considered deleted because it has a reference variable which refers to nothing. So one cannot declare a variable of type F
like so: F variableName;
as there will be errors such as: uninitialized reference member in struct F
.
I understand this however I do not understand what such a structure would be good for if you cannot even declare a variable of its type. Could such a data type be useful in some specific case?
The copy constructor and copy-assignment operator are public but deleted. It is a compile-time error to define or call a deleted function.
If no user-defined constructors are present and the implicitly-declared default constructor is not trivial, the user may still inhibit the automatic generation of an implicitly-defined default constructor by the compiler with the keyword delete.
When to delete copy constructor and assignment operator? Copy constructor (and assignment) should be defined when ever the implicitly generated one violates any class invariant. It should be defined as deleted when it cannot be written in a way that wouldn't have undesirable or surprising behaviour.
In another way, = delete means that the compiler will not generate those constructors when declared and this is only allowed on copy constructor and assignment operator. There is also = 0 usage; it means that a function is purely virtual and you cannot instantiate an object from this class.
Since F
is an aggregate you can use aggregate initialization:
int a = 42;
F f1 = {a, 13};
// or
F f2{a, 9};
Live demo.
A class type (typically, struct or union) is an aggregate if it has:
- no private or protected non-static data members
- no user-provided, inherited, or explicit (since C++17) constructors (explicitly defaulted or deleted constructors are allowed) (since C++11)
- no virtual, private, or protected (since C++17) base classes
- no virtual member functions
I understand this however I do not understand what such structure would be good for if you cannot even declare a variable of it's type. Could such a data type be useful in some specific case?
The implicitly defaulted constructor being deleted doesn't mean you can't use this type ever. It means you must define the constructor yourself, because only you, the programmer, can know what that reference should be bound to. So the compiler is leaving it up to you, and if you forget, you'll be notified the c'tor is deleted.
That's why it's deleted, but as folks mentioned, that in itself doesn't mean you can't use that structure as is. It's still possible to aggregate initialize it (won't be possible if it had private data members however, so there's that to consider too).
A simple use case may be to alias members. For instance (this is kind of a toy example, you can use default member initializers instead):
struct Point {
double coord[3];
double& x;
double& y;
double& z;
Point() : x(coord[0]), y(coord[1]), z(coord[2]) {}
};
Reference members also mean you would need to provide definitions for other member function to ensure your objects operate correctly, since they complicate matters somewhat. This is why they are usually avoided.
Other uses cannot really be enumerated exhaustively.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With