C ++ удаленные конструкторы - PullRequest
0 голосов
/ 01 мая 2018

Скажите, у меня есть эта структура:

struct F
{
    int& ref; // reference member
    const int c; // const member
    // F::F() is implicitly defined as deleted
};

Это из cppreference. Как я понимаю из документации, конструктор F считается удаленным, потому что он имеет ссылочную переменную, которая ни на что не ссылается. Поэтому нельзя объявить переменную типа F следующим образом: F variableName;, так как будут ошибки, такие как: неинициализированный ссылочный член в структуре F.

Я понимаю это, однако я не понимаю, для чего будет полезна такая структура, если вы даже не можете объявить переменную ее типа. Может ли такой тип данных быть полезным в каком-то конкретном случае?

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Так как F является агрегатом, вы можете использовать агрегатная инициализация :

int a = 42;
F f1 = {a, 13};

// or

F f2{a, 9};

Демонстрационная версия .

Тип класса (обычно struct или union) является агрегатом, если он имеет:

  • нет личных или защищенных нестатических элементов данных
  • нет пользовательских, унаследованных или явных (начиная с C ++ 17) конструкторов (допускаются явно заданные по умолчанию или удаленные конструкторы) (начиная с C ++ 11)
  • нет виртуальных, частных или защищенных (начиная с C ++ 17) базовых классов
  • нет виртуальных функций-членов
0 голосов
/ 01 мая 2018

Я понимаю это, однако я не понимаю, для чего будет полезна такая структура, если вы даже не можете объявить переменную ее типа. Может ли такой тип данных быть полезным в каком-то конкретном случае?

Удаление неявно используемого по умолчанию конструктора не означает, что вы никогда не сможете использовать этот тип. Это означает, что вы должны определить конструктор самостоятельно, потому что только вы, программист, можете знать, к чему должна быть привязана эта ссылка. Таким образом, компилятор оставляет это на ваше усмотрение, и если вы забудете, вы получите уведомление о том, что c'tor удален.

Вот почему он удален, но, как уже упоминалось, это само по себе не означает, что вы не можете использовать эту структуру как есть. Все еще возможно агрегировать его инициализацию (однако это невозможно, если бы у него были частные элементы данных, так что это тоже нужно учитывать).

Простым вариантом использования может быть псевдоним членов. Например (это своего рода игрушечный пример, вы можете вместо этого использовать инициализаторы членов по умолчанию):

struct Point {
  double coord[3];
  double& x;
  double& y;
  double& z;

  Point() : x(coord[0]), y(coord[1]), z(coord[2]) {}
};

Ссылочные члены также означают, что вам потребуется предоставить определения для других функций-членов, чтобы обеспечить правильную работу ваших объектов, поскольку они несколько усложняют ситуацию. Вот почему их обычно избегают.

Другое использование не может быть исчерпывающе перечислено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...