Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ deleted constructors

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?

like image 396
Cantaff0rd Avatar asked May 01 '18 07:05

Cantaff0rd


People also ask

What is deleted copy constructor?

The copy constructor and copy-assignment operator are public but deleted. It is a compile-time error to define or call a deleted function.

Can default constructor be deleted?

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 should you delete copy constructor?

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.

What is delete for in constructor C++?

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.


2 Answers

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
like image 188
Chris Drew Avatar answered Oct 24 '22 09:10

Chris Drew


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.

like image 6
StoryTeller - Unslander Monica Avatar answered Oct 24 '22 07:10

StoryTeller - Unslander Monica