A
A
Anton Prikazchikov2018-04-25 17:44:15
C++ / C#
Anton Prikazchikov, 2018-04-25 17:44:15

What is the reason for the "use of deleted function" compiler error in this code?

Hey!
Please explain the cause of the error in the following code:

// Класс создающий объекты и предоставляющий к ним доступ
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);

Trying to instantiate a class with copy and move constructors removed:
// Класс
class MyClass
{
public:
MyClass(){}
MyClass(const MyClass&) = delete;
MyClass(MyClass&&) = delete;
};
//Код вызова
Singleton<MyClass>::create();

And I get a compiler error:
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;

I understand that the compiler wants a constructor, but why does he want one? Tell me where to read about it

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Ariox41, 2018-04-26
@Ariox41

Just replace the parentheses with curly ones in the initialization list: example .
An empty list of arguments cannot be passed to the constructor through parentheses - otherwise it will be equivalent to a string MyClass value();- and this is a function declaration. Because of this, an empty argument list is interpreted as an empty initialization list, but again, an empty initialization list cannot be passed to a constructor with no arguments using parentheses, because there is one argument. But when using curly braces, the initialization list normally calls the no-argument constructor. At the same time, implicit conversion from an empty initialization list to MyClass is possible - the constructor without arguments is implicitly called:

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

This means that the string will be MyClass({})converted {}to a temporary object MyClass, and it will try to pass it to the remote move constructorMyClass

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question