Почему переменная-член класса вызывает конструктор удаленной копии, а локальная переменная вызывает конструктор? - PullRequest
0 голосов
/ 06 января 2020

Я пытаюсь определить переменную-член для класса, используя существующий тип класса, который удаляет его конструктор копирования. Когда я пытаюсь определить переменную-член, я получаю ошибку времени компиляции

test2.cpp:25:24: error: use of deleted function 'UseDelDef::UseDelDef(UseDelDef&&)

Но, когда я вместо этого определяю локальную переменную, проблем не возникает. Я понимаю, что определение переменной-члена вызывает конструктор по умолчанию для класса ... как мне обойти это без изменения существующего класса? Я немного c ++ n00b ...;) Для справки, я застрял с c ++ 14

Вот код для test2. cpp:

class DelDef
{
public:
  DelDef() {}
private:
  DelDef(const DelDef &other) = delete;
};

class UseDelDef
{
public:
  UseDelDef()
  {
    // This is fine...
    DelDef del_def;
  }
private:
   // This calls the default constructor
   // causes a compile error 'use of deleted function'
   DelDef m_del_def;
};

int main()
{
  auto udd = UseDelDef();
}

1 Ответ

3 голосов
/ 06 января 2020
// This is fine...
DelDef del_def;

Это нормально, потому что используется инициализация по умолчанию. DelDef и UseDelDef оба по умолчанию инициализируются.

auto udd = UseDelDef();

До C ++ 17 это значение инициализирует временный UseDelDef (что нормально) и затем копирует -инициализируется udd из временного (ходом). Это неправильно сформировано, потому что UseDelDef не является подвижным (потому что DelDef не является подвижным (из-за конструктора удаленной копии)).

Начиная с C ++ 17, программа хорошо сформирована, потому что udd инициализируется непосредственно из выражения, которое используется для инициализации выражения prvalue, и временный объект не задействован (это изменение правил называлось «гарантированное исключение копирования»). Вы можете исправить это для pre-C ++ 17, просто используя инициализацию по умолчанию вместо инициализации копирования, как вы использовали в конструкторе:

int main()
{
    UseDelDef udd;
}

Или вы можете использовать компилятор, соответствующий C ++ 17.

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