Russian Qt Forum
Март 28, 2024, 21:08 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: std::unique_ptr  (Прочитано 21479 раз)
AzazelloAV
Гость
« : Июнь 21, 2017, 12:02 »

Код:
class Q_DECL_EXPORT SmiModuleTypes
{
    struct Types;
private:
    std::vector<std::unique_ptr<Types>> mTypes;
};

ошибка: C2280: 'std::unique_ptr<SmiModuleTypes::Types,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function
with
[
    _Ty=SmiModuleTypes::Types
]

Дальше интересней.
Код:
class Q_DECL_EXPORT SmiModuleTypes
{
    struct Types;
private:
    std::unique_ptr<Types> mDump; ///!!!!!!!!!!!!!!!!
    std::vector<std::unique_ptr<Types>> mTypes;
};

Добавляем строку (см поле mDump) - все ок.
Также ок и первый вариант, если убрать  Q_DECL_EXPORT

Наблюдается под VC 14.0. Под gcc Ок.
Мыслей нету.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #1 : Июнь 21, 2017, 15:55 »

Не вижу объявления Types
Записан
AzazelloAV
Гость
« Ответ #2 : Июнь 21, 2017, 18:49 »

Не вижу объявления Types

Объявления Types в реализации. Также добавте сюда всякие = default.
Заметте, компилируется и РАБОТАЕТ при добавлении неиспользуемой переменной std::unique_ptr<Types> mDump; ///!!!!!!!!!!!!!!!!

Это не единичная ошибка, где "что-то не досмотрел". Танцевал с двумя разными классами так, результат один и тот же.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #3 : Июнь 21, 2017, 19:03 »

Если объявление в реализации, то конструктор и деструктор использующего класса тоже должны быть там же, иначе компилятор пытается их инлайнить и не знает, как создать/удалить класс. Возможно, проблема в этом.
Записан
AzazelloAV
Гость
« Ответ #4 : Июнь 21, 2017, 19:12 »

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

Нет, не в этом. Я указал, что всякие дефаулты конструкторов указаны.  В моем случае они находятся  в реализации. Я привел псевдокод. Ну суть даже не в этом. Допустим я действительно "все сделал не правильно", однако добавление некоторых магических символов делает мой код компилируемым.

Если интересно, могу произвести ситуацию в чистом виде. Qt5, VS 14
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #5 : Июнь 21, 2017, 20:20 »

Но ведь компилятор не знает о том, что они дефолтные, когда он включает хедер, у него нет такой информации.
Но вообще, похоже на баг. Осталось понять, чего:)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Июнь 22, 2017, 08:33 »

Было подобное. Одни компиляторы не интересуются типом до момента "инстанциации", а другие его требуют
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #7 : Июнь 22, 2017, 09:17 »

Сделайте деструктор неинлайн
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #8 : Июнь 22, 2017, 09:20 »

Код
C++ (Qt)
SmiModuleTypes {
   ~SmiModuleTypes();
};
SmiModuleTypes::~SmiModuleTypes() = default;
Записан
AzazelloAV
Гость
« Ответ #9 : Июнь 22, 2017, 10:26 »

Код
C++ (Qt)
SmiModuleTypes {
   ~SmiModuleTypes();
};
SmiModuleTypes::~SmiModuleTypes() = default;

Повторюсь.
Цитировать
Также добавте сюда всякие = default.
Это псевдокод! Вы же не спрашиваете, зачем класс, в котором нет ни одного метода.
Записан
AzazelloAV
Гость
« Ответ #10 : Июнь 22, 2017, 10:27 »

Но ведь компилятор не знает о том, что они дефолтные, когда он включает хедер, у него нет такой информации.
Но вообще, похоже на баг. Осталось понять, чего:)

Да не привел я дефолтные просто. В уме добавте я имел в виду.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Июнь 22, 2017, 10:53 »

Ну если уж пошла такая пьянка, то что-нибудь типа
Код:
private:
   Types * mDummy;   // to make MSVC happy

    std::vector<std::unique_ptr<Types>> mTypes;
};
У меня подобных ой не один  Улыбающийся
Записан
AzazelloAV
Гость
« Ответ #12 : Июнь 22, 2017, 15:38 »

Ну если уж пошла такая пьянка, то что-нибудь типа
Код:
private:
   Types * mDummy;   // to make MSVC happy

    std::vector<std::unique_ptr<Types>> mTypes;
};
У меня подобных ой не один  Улыбающийся

Спасибо, понял, что не только у меня такое....
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #13 : Август 08, 2018, 18:15 »


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

пример:
Код:
#include <vector>
#include <memory>

 
int main()
{

    struct type{};
   
    using container = std::vector< std::unique_ptr<type> >;
   
   
    container s1;
   
    container s2 = s1;
}


выхлоп:

Цитировать
error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.18 секунд. Запросов: 23.