Ошибка use of deleted function

The error message clearly says that the default constructor has been deleted implicitly. It even says why: the class contains a non-static, const variable, which would not be initialized by the default ctor.

class X {
    const int x;
};

Since X::x is const, it must be initialized — but a default ctor wouldn’t normally initialize it (because it’s a POD type). Therefore, to get a default ctor, you need to define one yourself (and it must initialize x). You can get the same kind of situation with a member that’s a reference:

class X { 
    whatever &x;
};

It’s probably worth noting that both of these will also disable implicit creation of an assignment operator as well, for essentially the same reason. The implicit assignment operator normally does members-wise assignment, but with a const member or reference member, it can’t do that because the member can’t be assigned. To make assignment work, you need to write your own assignment operator.

This is why a const member should typically be static — when you do an assignment, you can’t assign the const member anyway. In a typical case all your instances are going to have the same value so they might as well share access to a single variable instead of having lots of copies of a variable that will all have the same value.

It is possible, of course, to create instances with different values though — you (for example) pass a value when you create the object, so two different objects can have two different values. If, however, you try to do something like swapping them, the const member will retain its original value instead of being swapped.

Привет!
Прошу пояснить причину ошибки в следующем коде:

// Класс создающий объекты и предоставляющий к ним доступ
template<typename T>
class Singleton
{
public:
    /*!
     * brief Создание экземпляра класса
     */
    template<typename ... Args>
    inline static void create(Args ... arsg)
    {
        if (m_pInstance != nullptr)
            return;

        static T instance(arsg...);
        m_pInstance = &instance;
    }

    /*!
     * brief Доступ к экземпляру класса по ссылке
     */
    inline static T& get()
    {
        assert(m_pInstance && "Singleton is not initialized!");
        return *m_pInstance;
    }

    Singleton() = delete;
    ~Singleton() = delete;
    
    Singleton(const Singleton&) = delete;
    Singleton& operator =(const Singleton&) = delete;

    Singleton(Singleton&&) = delete;
    Singleton& operator =(Singleton&&) = delete;

private:
    static T* m_pInstance;
};

template<typename T>
T* Singleton<T>::m_pInstance(nullptr);

Пытаюсь создать экземпляр класса с удаленными конструкторами копирования и перемещения:

// Класс
class MyClass
{
public:
MyClass(){}
MyClass(const MyClass&) = delete;
MyClass(MyClass&&) = delete;
};
//Код вызова
Singleton<MyClass>::create();

И получаю ошибку компилятора:

Singleton.h: In instantiation of ‘static void Singleton::create(Args …) [with Args = {}; T = MyClass]’:
mycode.cpp:16:47: required from here
Singleton.h:34:34: error: use of deleted function ‘MyClass(MyClass&&)’
static T instance(arsg…);
^
In file included from mycode.cpp:6:0:
mycode.h:82:5: note: declared here
MyClass(MyClass&& orig) = delete;

Понимаю что компилятор хочет конструктор, но почему он его хочет? Подскажите где про это почитать


  • Вопрос задан

    более трёх лет назад

  • 2431 просмотр

Пригласить эксперта

Просто замените круглые скобки на фигурные в списке инициализации: пример.

Пустой список аргументов не может быть передан в конструктор через круглые скобки — иначе это будет эквивалентно строке MyClass value(); — а это уже объявление функции. Из-за этого пустой список аргументов интерпретироваться как пустой список инициализации, но пустой список инициализации опять же нельзя передать в конструктор без аргументов, используя круглые скобки, т.к. один аргумент всё-таки есть. Но при использовании фигурных скобок список инициализации нормально вызывает конструктор без аргументов. При этом неявное преобразование из пустого списка инициализации в MyClass возможно — неявно вызывается конструктор без аргументов:

void foo(MyType2&&){ }
foo({}); // Компилируется

А значит строка MyClass({}) преобразует {} во временный объектMyClass, а его попытается передать в удалённый конструктор перемещения MyClass


  • Показать ещё
    Загружается…

09 июн. 2023, в 23:05

80000 руб./за проект

09 июн. 2023, в 22:45

1000 руб./за проект

09 июн. 2023, в 22:39

1000 руб./в час

Минуточку внимания

  • Forum
  • Beginners
  • use of deleted function

use of deleted function

Hi,
I have defined two constructors, one default and one with init parameters:

1
2
    Complex();
    Complex(double &x, double &iy) { m_x = x; m_iy = iy;}

Furthermore I have defined these operators:

1
2
3
4
5
    Complex& operator=(Complex& other);
    Complex& operator=(Complex&& other);
    Complex& operator=(const Complex& other);
    Complex& operator=(const Complex&& other);
    Complex& operator=(const Complex other);

But when I use the second constructor, as in here

This is marked as «error: use of deleted function ‘constexpr Complex::Complex(const Complex&)’
Complex Complex::squared(Complex &c) {return c.squared(); }»

I have tried to define

1
2
3
4
5
    constexpr Complex& operator=(const Complex &other) const {
        m_x = other.x();
        m_iy = other.iy();
        return *this;
    }

But this causes the following errors:
1st line: «no return statement in constexpr function»
2nd/3rd line: «cannot assign to non-static data member within const member function ‘operator='»
4th line: «binding value of type ‘const Complex’ to reference to type ‘Complex’ drops ‘const’ qualifier»

I obviously haven’t sufficiently understood the concept of contexpr (and others).

Any idea how to satisfy the compiler?

^

Hm. Seems that defining

1
2
3
4
5
    Complex(const Complex &c)
        {
             m_x = c.x();
             m_iy = c.iy();
        }

and — to avoid ambiguity — limiting my operator= definitions to one

 
Complex& operator=(Complex& other);

might have done the trick.

Last edited on

Topic archived. No new replies allowed.

parsecer

3 / 3 / 2

Регистрация: 19.07.2015

Сообщений: 74

1

11.02.2016, 00:27. Показов 9830. Ответов 3

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

У меня есть два класса: Dog и Owner. В классе Dog есть public static член, имеющий тип Owner & (ссылка на экземпляр класса Owner). Но при попытке это все реализовать, возникает ошибка «use of deleted function ‘Dog& Dog::operator=(const Dog&)». Вот код классов и их конструкторов:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Dog 
    {
       private:
         Owner & m_owner;
         ...
       public:
           static Owner & m_breeder;
         ...
    }
 
class Owner
    {private:
         ...
     public:
         ...
      }

dog_methods.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 {
    #include "dog_class.h"
    #include <iostream>
    #include <cstdlib>
    #include <string>
    #include <ctime>
 
    Owner breeder("breeder");
    Owner & Dog::m_breeder=breeder;
    //methods here
    Dog () : m_owner(m_breeder) {}
 
Dog::Dog(std::string name, int size, int status, int loyalty, int sex, int price, std::vector<Dog> * market, Owner & owner) : m_owner(owner)
{
m_name=name;
m_size=size;
m_status=status;
m_loyalty=loyalty;
 
m_sex=sex;
m_price=price;
m_market=market; //pointer to the market
m_market->push_back(*this);
//break_out();
 }
 
 
 
  Dog::Dog() : m_owner(m_breeder)
{
m_name="Fang";
srand(time(NULL));
m_size=(rand()%10)+1; //small: random number from 1 to 10;
m_status=0; //not owned
m_loyalty=(rand()%10)+1; //from 1 to 10
Owner no_one("no_one");
//m_owner=no_one;
m_sex=rand()%2; //rand 0 or 1;
m_price=rand()%1001; //0 - 1000;
//show_data();
//break_out();
 }

owner_methods.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Owner::Owner()
{
 
m_name="random";
m_goodness=(rand()%10+1);
m_size=(rand()%10+1);
m_money=rand()%1001;
m_agility=(rand()%10+1);
m_int=(rand()%10+1);
//std::cout<<"Hi! I am the "<<m_name<<std::endl;
 }
  Owner::Owner(std::string name)
 {
 if (name=="no one")
 {
m_name="no one";
m_goodness=0;
m_size=0;
m_money=0;
m_agility=0;
m_int=0;
std::cout<<"Hi! I am the "<<m_name<<std::endl;
   }
   else
  {
m_name=name;
m_goodness=(rand()%10+1);
m_size=(rand()%10+1);
m_money=rand()%1001;
m_agility=(rand()%10+1);
m_int=(rand()%10+1);
std::cout<<"The '"<<m_name<<"' owner made"<<std::endl;
    }
  }
 
 
 Owner::Owner(std::string name, int goodness, int size, int money, int    agility, std::vector<Dog> doglist)
  {
m_name=name;
m_size=size;
m_money=money;
m_agility=agility;
for (int i=0;  i<doglist.size();i++)
    m_doglist.push_back(doglist[i]);
  }



0



17427 / 9259 / 2264

Регистрация: 30.01.2014

Сообщений: 16,215

11.02.2016, 00:34

2

Лучший ответ Сообщение было отмечено parsecer как решение

Решение

parsecer, оператор присваивания в классе Dog опиши явно. Он deleted потому что ссылки не присваиваются (не переназначаются). Обыграй это как-то сам в операторе.



1



3 / 3 / 2

Регистрация: 19.07.2015

Сообщений: 74

11.02.2016, 00:42

 [ТС]

3

Спасибо за ответ, а что вызвало данную ошибку? В main присваивания Dog=Dog нигде не используется.



0



17427 / 9259 / 2264

Регистрация: 30.01.2014

Сообщений: 16,215

11.02.2016, 00:45

4

Цитата
Сообщение от parsecer
Посмотреть сообщение

Спасибо за ответ, а что вызвало данную ошибку?

Вектор требует от своих элементов быть либо copy-assignable, либо move-assignable.



1



Hello Tobias,

I spent three more hour to try to make work Veyon 4.0.0 :
Master : Windows 10
Client : Opensuse Leap 42.2 with your rpm

I tried all possibilities, really. No way.
I tworked in june. Now it will not work.

I tried my certificates that worked in june.
I tried new certificates.
I tried auth with logon.
I installed a new fresh Leap 42.2.

Here is the «loop error» a have with old or new certificates, or logon,
when I start veyon-service on the Leap client and then veyon master on
windows 10 :

I hope you can help.
Thanks in advance,

Vincent

Понравилась статья? Поделить с друзьями:
  • Ошибка usb устройство работает неправильно
  • Ошибка usb устройство не опознано код 43
  • Ошибка usb устройства в машине
  • Ошибка usb устройств код 43
  • Ошибка usb устранить на windows 7 не видит устройство